]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix ICE with requires-expression in lambda requires-clause [PR123080]
authorEgas Ribeiro <egas.g.ribeiro@gmail.com>
Thu, 25 Dec 2025 12:33:47 +0000 (12:33 +0000)
committerJason Merrill <jason@redhat.com>
Mon, 29 Dec 2025 15:07:43 +0000 (22:07 +0700)
When parsing a lambda with a trailing requires-clause, calling
cp_parser_requires_clause_opt confused generic lambda parsing when
implicit template parameters were involved.
After failing to parse a type-requirement during tentative parsing and
hitting error recovery code in cp_parser_skip_to_end_of_statement that
aborted the current implicit template, attemping to finish the lambda
declaration caused ICEs.

Fix this by not aborting the current implicit template during tentative
parsing and adding cleanup for fully_implicit_function_template_p.

PR c++/123080

gcc/cp/ChangeLog:

* parser.cc (cp_parser_skip_to_end_of_statement): Don't abort
implicit templates during tentative parsing.
(cp_parser_lambda_declarator_opt): Add cleanup for
fully_implicit_function_template_p before parsing
trailing_requires_clause.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/lambda-requires6.C: New test.
* g++.dg/cpp2a/lambda-requires6a.C: New test.

Signed-off-by: Egas Ribeiro <egas.g.ribeiro@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/parser.cc
gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/lambda-requires6a.C [new file with mode: 0644]

index 26da789f821878a0110df84eaea0046280cc77f9..9ec3b21ab7f7631a8b9dcab30e2b1d57e61aca8e 100644 (file)
@@ -4288,7 +4288,8 @@ cp_parser_skip_to_end_of_statement (cp_parser* parser)
   unsigned nesting_depth = 0;
 
   /* Unwind generic function template scope if necessary.  */
-  if (parser->fully_implicit_function_template_p)
+  if (parser->fully_implicit_function_template_p
+      && !cp_parser_parsing_tentatively (parser))
     abort_fully_implicit_template (parser);
 
   while (true)
@@ -12748,6 +12749,9 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr,
 
   if (has_param_list)
     {
+      /* Avoid ICE on lambda-requires6a.C.  */
+      auto cleanup
+       = make_temp_override (parser->fully_implicit_function_template_p);
       /* Parse optional trailing requires clause.  */
       trailing_requires_clause = cp_parser_requires_clause_opt (parser, false);
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C b/gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C
new file mode 100644 (file)
index 0000000..eada677
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/123080
+// { dg-do compile { target c++20 } }
+template<typename T> struct type_identity { using type = T; };
+auto f = [](auto x) requires requires { typename type_identity<decltype(x)>::type(0); } {};
+int main() { f(0); }
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-requires6a.C b/gcc/testsuite/g++.dg/cpp2a/lambda-requires6a.C
new file mode 100644 (file)
index 0000000..54e7234
--- /dev/null
@@ -0,0 +1,3 @@
+// PR c++/123080
+// { dg-do compile { target c++20 } }
+auto f = [](auto x) requires requires { // { dg-error "expected | invalid member template | constraints" }