aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constraint.cc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-09-17 09:16:02 -0400
committerPatrick Palka <ppalka@redhat.com>2020-09-17 09:16:02 -0400
commitb28b621ac67beee81a47adb50b954bcf751570fd (patch)
tree8fa20ad6c88d0c2bf9f95239a059df843e92bad2 /gcc/cp/constraint.cc
parent9fcedcc39153cb3cfa08ebab20aef6cdfb9ed609 (diff)
downloadgcc-b28b621ac67beee81a47adb50b954bcf751570fd.zip
gcc-b28b621ac67beee81a47adb50b954bcf751570fd.tar.gz
gcc-b28b621ac67beee81a47adb50b954bcf751570fd.tar.bz2
c++: requires-expressions and partial instantiation [PR96410]
This patch makes tsubst_requires_expr avoid substituting into a requires-expression when partially instantiating a generic lambda. This is necessary in general to ensure that we always check requirements in lexical order (as in the first testcase below). A mechanism similar to PACK_EXPANSION_EXTRA_ARGS is added to remember template arguments and defer substitution of requires-expressions. Incidentally, this change also fixes the two mentioned PRs -- the problem there is that tsubst_requires_expr was performing semantic checks on template trees, and some of the checks are not prepared to handle such trees. With this patch, tsubst_requires_expr no longer does any semantic checking at all when processing_template_decl. gcc/cp/ChangeLog: PR c++/96409 PR c++/96410 * constraint.cc (tsubst_requires_expr): Use REQUIRES_EXPR_PARMS and REQUIRES_EXPR_REQS. Use REQUIRES_EXPR_EXTRA_ARGS, add_extra_args and build_extra_args to defer substitution until we have all the template arguments. (finish_requires_expr): Adjust the call to build_min so that REQUIRES_EXPR_EXTRA_ARGS gets set to NULL_TREE. * cp-tree.def (REQUIRES_EXPR): Give it a third operand. * cp-tree.h (REQUIRES_EXPR_PARMS, REQUIRES_EXPR_REQS, REQUIRES_EXPR_EXTRA_ARGS): Define. (add_extra_args, build_extra_args): Declare. gcc/testsuite/ChangeLog: PR c++/96409 PR c++/96410 * g++.dg/cpp2a/concepts-lambda13.C: New test. * g++.dg/cpp2a/concepts-lambda14.C: New test.
Diffstat (limited to 'gcc/cp/constraint.cc')
-rw-r--r--gcc/cp/constraint.cc21
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index ad9d470..0aab307 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2175,7 +2175,19 @@ tsubst_requires_expr (tree t, tree args,
/* A requires-expression is an unevaluated context. */
cp_unevaluated u;
- tree parms = TREE_OPERAND (t, 0);
+ args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args);
+ if (processing_template_decl)
+ {
+ /* We're partially instantiating a generic lambda. Substituting into
+ this requires-expression now may cause its requirements to get
+ checked out of order, so instead just remember the template
+ arguments and wait until we can substitute them all at once. */
+ t = copy_node (t);
+ REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, complain);
+ return t;
+ }
+
+ tree parms = REQUIRES_EXPR_PARMS (t);
if (parms)
{
parms = tsubst_constraint_variables (parms, args, info);
@@ -2183,14 +2195,11 @@ tsubst_requires_expr (tree t, tree args,
return boolean_false_node;
}
- tree reqs = TREE_OPERAND (t, 1);
+ tree reqs = REQUIRES_EXPR_REQS (t);
reqs = tsubst_requirement_body (reqs, args, info);
if (reqs == error_mark_node)
return boolean_false_node;
- if (processing_template_decl)
- return finish_requires_expr (cp_expr_location (t), parms, reqs);
-
return boolean_true_node;
}
@@ -2933,7 +2942,7 @@ finish_requires_expr (location_t loc, tree parms, tree reqs)
}
/* Build the node. */
- tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs);
+ tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs, NULL_TREE);
TREE_SIDE_EFFECTS (r) = false;
TREE_CONSTANT (r) = true;
SET_EXPR_LOCATION (r, loc);