c++: Some preparatory type canonicalization fixes
The patches that follow revealed some latent type canonicalization issues during normalization/satisfaction, due to normalization of some constraint-expressions now being performed in different contexts and more frequently (since the normalization caches get frequently emptied in a checking compiler). The issues are: 1. In tsubst_parameter_mapping, we canonicalize the arguments of a substituted TYPE_ARGUMENT_PACK only if the argument we started with wasn't a TYPE_ARGUMENT_PACK. We should canonicalize a substituted TYPE_ARGUMENT_PACK regardless of what we started with. 2. We currently set DECL_CONTEXT and CONSTRAINT_VAR_P on each of the parameters introduced in a requires expression _after_ we're done processing the requirements. But meanwhile we may have already built and computed the canonical form of a type that uses one of these PARM_DECLs (as say an operand to decltype). But the canonical form depends on the result of cp_tree_equal, which in turn depends on the value of CONSTRAINT_VAR_P and DECL_CONTEXT. So we must set these fields earlier, before processing requirements. 3. In do_auto_deduction, we use the result of finish_decltype_type later as a template argument, so we should canonicalize the result too. (While we're here, we should pass 'complain' to finish_decltype_type, which fixes the testcase auto1.C below.) gcc/cp/ChangeLog: * constraint.cc (tsubst_parameter_mapping): Canonicalize the arguments of a substituted TYPE_ARGUMENT_PACK even if we've started with a TYPE_ARGUMENT_PACK. (finish_requires_expr): Don't set DECL_CONTEXT and CONSTRAINT_VAR_P on each of the introduced parameters here. * parser.c (cp_parser_requirement_parameter_list): Instead set these fields earlier, here. * pt.c (do_auto_deduction): Canonicalize the result of do_auto_deduction. Pass 'complain' to finish_decltype_type. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/auto1.C: New test.
This commit is contained in:
parent
d6378b9785
commit
04b10596fe
4 changed files with 39 additions and 19 deletions
|
@ -2319,15 +2319,15 @@ tsubst_parameter_mapping (tree map, tree args, subst_info info)
|
|||
new_arg = tsubst_template_arg (arg, args, complain, in_decl);
|
||||
if (TYPE_P (new_arg))
|
||||
new_arg = canonicalize_type_argument (new_arg, complain);
|
||||
if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
|
||||
}
|
||||
if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
|
||||
{
|
||||
tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
|
||||
for (int i = 0; i < TREE_VEC_LENGTH (pack_args); i++)
|
||||
{
|
||||
tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
|
||||
for (int i = 0; i < TREE_VEC_LENGTH (pack_args); i++)
|
||||
{
|
||||
tree& pack_arg = TREE_VEC_ELT (pack_args, i);
|
||||
if (TYPE_P (pack_arg))
|
||||
pack_arg = canonicalize_type_argument (pack_arg, complain);
|
||||
}
|
||||
tree& pack_arg = TREE_VEC_ELT (pack_args, i);
|
||||
if (TYPE_P (pack_arg))
|
||||
pack_arg = canonicalize_type_argument (pack_arg, complain);
|
||||
}
|
||||
}
|
||||
if (new_arg == error_mark_node)
|
||||
|
@ -3253,15 +3253,6 @@ evaluate_concept_check (tree check, tsubst_flags_t complain)
|
|||
tree
|
||||
finish_requires_expr (location_t loc, tree parms, tree reqs)
|
||||
{
|
||||
/* Modify the declared parameters by removing their context
|
||||
so they don't refer to the enclosing scope and explicitly
|
||||
indicating that they are constraint variables. */
|
||||
for (tree parm = parms; parm; parm = DECL_CHAIN (parm))
|
||||
{
|
||||
DECL_CONTEXT (parm) = NULL_TREE;
|
||||
CONSTRAINT_VAR_P (parm) = true;
|
||||
}
|
||||
|
||||
/* Build the node. */
|
||||
tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (r) = false;
|
||||
|
|
|
@ -28817,6 +28817,18 @@ cp_parser_requirement_parameter_list (cp_parser *parser)
|
|||
if (!parens.require_close (parser))
|
||||
return error_mark_node;
|
||||
|
||||
/* Modify the declared parameters by removing their context
|
||||
so they don't refer to the enclosing scope and explicitly
|
||||
indicating that they are constraint variables. */
|
||||
for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
|
||||
{
|
||||
if (parm == void_list_node || parm == explicit_void_list_node)
|
||||
break;
|
||||
tree decl = TREE_VALUE (parm);
|
||||
DECL_CONTEXT (decl) = NULL_TREE;
|
||||
CONSTRAINT_VAR_P (decl) = true;
|
||||
}
|
||||
|
||||
return parms;
|
||||
}
|
||||
|
||||
|
|
|
@ -29517,9 +29517,13 @@ do_auto_deduction (tree type, tree init, tree auto_node,
|
|||
|| ((TREE_CODE (init) == COMPONENT_REF
|
||||
|| TREE_CODE (init) == SCOPE_REF)
|
||||
&& !REF_PARENTHESIZED_P (init)));
|
||||
tree deduced = finish_decltype_type (init, id, complain);
|
||||
deduced = canonicalize_type_argument (deduced, complain);
|
||||
if (deduced == error_mark_node)
|
||||
return error_mark_node;
|
||||
targs = make_tree_vec (1);
|
||||
TREE_VEC_ELT (targs, 0)
|
||||
= finish_decltype_type (init, id, tf_warning_or_error);
|
||||
TREE_VEC_ELT (targs, 0) = deduced;
|
||||
/* FIXME: These errors ought to be diagnosed at parse time. */
|
||||
if (type != auto_node)
|
||||
{
|
||||
if (complain & tf_error)
|
||||
|
|
13
gcc/testsuite/g++.dg/cpp1z/auto1.C
Normal file
13
gcc/testsuite/g++.dg/cpp1z/auto1.C
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Verify that deduction failure of the decltype(auto) template parameter is
|
||||
// a SFINAE error.
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
template <class> void f();
|
||||
template <class> void f(int);
|
||||
|
||||
template <class T = int, decltype(auto) = &f<T>> void g();
|
||||
template <class = int> void g();
|
||||
|
||||
int main() {
|
||||
g();
|
||||
}
|
Loading…
Add table
Reference in a new issue