aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-04-01 12:01:30 -0400
committerPatrick Palka <ppalka@redhat.com>2023-04-01 12:01:30 -0400
commita5de246535db1b4fdc61287f27de0fdd074fc4b3 (patch)
tree2da00af879eeb6d4c767d2ca5be94a388a721cda /gcc/cp/pt.cc
parentb5e38b1c166357e2a63d38ae6da7ae5d68fc115b (diff)
downloadgcc-a5de246535db1b4fdc61287f27de0fdd074fc4b3.zip
gcc-a5de246535db1b4fdc61287f27de0fdd074fc4b3.tar.gz
gcc-a5de246535db1b4fdc61287f27de0fdd074fc4b3.tar.bz2
c++: NTTP constraint depending on outer parms [PR109160]
Here we're crashing during satisfaction for the NTTP 'C<B> auto V' ultimately because convert_template_argument / unify don't pass all outer template arguments to do_auto_deduction, and during satisfaction we need to know all arguments. While these callers do pass some outer arguments, they are only sufficient to properly substitute the (level-lowered) 'auto' and are not necessarily the entire set. Fortunately it seems these callers have access to the full set of outer arguments via convert_template_argument's 'in_decl' parameter and unify's 'tparms' parameter. So this patch adds a new parameter to do_auto_deduction, used only during adc_unify deduction, through which these callers can pass the enclosing (partially instantiated) template and from which do_auto_deduction can obtain _all_ outer template arguments for sake of satisfaction. This patch also ensures that the 'in_decl' argument passed to coerce_template_parms is always a TEMPLATE_DECL, which in turn allows us to pass it as-is to do_auto_deduction; the only coerce_template_parms caller that needed adjustment was tsubst_decl it seems. PR c++/109160 gcc/cp/ChangeLog: * cp-tree.h (do_auto_deduction): Add defaulted tmpl parameter. * pt.cc (convert_template_argument): Pass 'in_decl' as 'tmpl' to do_auto_deduction. (tsubst_decl) <case VAR_/TYPE_DECL>: Pass 'tmpl' instead of 't' as 'in_decl' to coerce_template_parms. (unify) <case TEMPLATE_PARM_INDEX>: Pass TPARMS_PRIMARY_TEMPLATE as 'tmpl' to do_auto_deduction. (do_auto_deduction): Document default arguments. Rename local variable 'tmpl' to 'ctmpl'. Use 'tmpl' to obtain a full set of template arguments for satisfaction in the adc_unify case. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-placeholder12.C: New test.
Diffstat (limited to 'gcc/cp/pt.cc')
-rw-r--r--gcc/cp/pt.cc32
1 files changed, 22 insertions, 10 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 022f295..4429ae6 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -8644,7 +8644,7 @@ convert_template_argument (tree parm,
else if (tree a = type_uses_auto (t))
{
t = do_auto_deduction (t, arg, a, complain, adc_unify, args,
- LOOKUP_IMPLICIT);
+ LOOKUP_IMPLICIT, /*tmpl=*/in_decl);
if (t == error_mark_node)
return error_mark_node;
}
@@ -15252,7 +15252,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
the template. */
argvec = (coerce_template_parms
(DECL_TEMPLATE_PARMS (gen_tmpl),
- argvec, t, complain));
+ argvec, tmpl, complain));
if (argvec == error_mark_node)
RETURN (error_mark_node);
hash = spec_hasher::hash (gen_tmpl, argvec);
@@ -24730,7 +24730,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
if (tree a = type_uses_auto (tparm))
{
tparm = do_auto_deduction (tparm, arg, a,
- complain, adc_unify, targs);
+ complain, adc_unify, targs,
+ LOOKUP_NORMAL,
+ TPARMS_PRIMARY_TEMPLATE (tparms));
if (tparm == error_mark_node)
return 1;
}
@@ -30779,13 +30781,20 @@ unparenthesized_id_or_class_member_access_p (tree init)
adc_requirement contexts to communicate the necessary template arguments
to satisfaction. OUTER_TARGS is ignored in other contexts.
- For partial-concept-ids, extra args may be appended to the list of deduced
- template arguments prior to determining constraint satisfaction. */
+ Additionally for adc_unify contexts TMPL is the template for which TYPE
+ is a template parameter type.
+
+ For partial-concept-ids, extra args from OUTER_TARGS, TMPL and the current
+ scope may be appended to the list of deduced template arguments prior to
+ determining constraint satisfaction as appropriate. */
tree
do_auto_deduction (tree type, tree init, tree auto_node,
- tsubst_flags_t complain, auto_deduction_context context,
- tree outer_targs, int flags)
+ tsubst_flags_t complain /* = tf_warning_or_error */,
+ auto_deduction_context context /* = adc_unspecified */,
+ tree outer_targs /* = NULL_TREE */,
+ int flags /* = LOOKUP_NORMAL */,
+ tree tmpl /* = NULL_TREE */)
{
if (init == error_mark_node)
return error_mark_node;
@@ -30821,9 +30830,9 @@ do_auto_deduction (tree type, tree init, tree auto_node,
/*return*/true)))
init = r;
- if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
+ if (tree ctmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
/* C++17 class template argument deduction. */
- return do_class_deduction (type, tmpl, init, flags, complain);
+ return do_class_deduction (type, ctmpl, init, flags, complain);
if (init == NULL_TREE || TREE_TYPE (init) == NULL_TREE)
/* Nothing we can do with this, even in deduction context. */
@@ -30975,7 +30984,10 @@ do_auto_deduction (tree type, tree init, tree auto_node,
}
}
- tree full_targs = add_to_template_args (outer_targs, targs);
+ tree full_targs = outer_targs;
+ if (context == adc_unify && tmpl)
+ full_targs = add_outermost_template_args (tmpl, full_targs);
+ full_targs = add_to_template_args (full_targs, targs);
/* HACK: Compensate for callers not always communicating all levels of
outer template arguments by filling in the outermost missing levels