aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/lambda.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2025-01-29 05:15:00 -0500
committerJason Merrill <jason@redhat.com>2025-04-04 15:40:08 -0400
commit25992d8daff60726a247ec7850d540aed5335639 (patch)
treeaf59650b5a8b270d61e512f5efe618402900b94c /gcc/cp/lambda.cc
parent2a36d22ab52d6ffce9a1fcaf7aca83336679e111 (diff)
downloadgcc-25992d8daff60726a247ec7850d540aed5335639.zip
gcc-25992d8daff60726a247ec7850d540aed5335639.tar.gz
gcc-25992d8daff60726a247ec7850d540aed5335639.tar.bz2
c++: lambda in requires outside template [PR99546]
Since r10-7441 we set processing_template_decl in a requires-expression so that we can use tsubst_expr to evaluate the requirements, but that confuses lambdas terribly; begin_lambda_type silently returns error_mark_node and we continue into other failures. This patch clears processing_template_decl again while we're defining the closure and op() function, so it only remains set while parsing the introducer (i.e. any init-captures) and building the resulting object. This properly avoids trying to create another lambda in tsubst_lambda_expr. PR c++/99546 PR c++/113925 PR c++/106976 PR c++/109961 PR c++/117336 gcc/cp/ChangeLog: * lambda.cc (build_lambda_object): Handle fake requires-expr processing_template_decl. * parser.cc (cp_parser_lambda_expression): Likewise. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-requires2.C: New test. * g++.dg/cpp2a/lambda-requires3.C: New test. * g++.dg/cpp2a/lambda-requires4.C: New test. * g++.dg/cpp2a/lambda-requires5.C: New test.
Diffstat (limited to 'gcc/cp/lambda.cc')
-rw-r--r--gcc/cp/lambda.cc8
1 files changed, 7 insertions, 1 deletions
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index ed70bb0..f0a54b6 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -59,7 +59,13 @@ build_lambda_object (tree lambda_expr)
vec<constructor_elt, va_gc> *elts = NULL;
tree node, expr, type;
- if (processing_template_decl || lambda_expr == error_mark_node)
+ if (processing_template_decl && !in_template_context
+ && current_binding_level->requires_expression)
+ /* As in cp_parser_lambda_expression, don't get confused by
+ cp_parser_requires_expression setting processing_template_decl. In that
+ case we want to return the result of finish_compound_literal, to avoid
+ tsubst_lambda_expr. */;
+ else if (processing_template_decl || lambda_expr == error_mark_node)
return lambda_expr;
/* Make sure any error messages refer to the lambda-introducer. */