From: Egas Ribeiro Date: Thu, 25 Dec 2025 12:33:47 +0000 (+0000) Subject: c++: Fix ICE with requires-expression in lambda requires-clause [PR123080] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=549bfeaa0bd2641ed99f1525caf3d54e2126396a;p=thirdparty%2Fgcc.git c++: Fix ICE with requires-expression in lambda requires-clause [PR123080] 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 Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 26da789f821..9ec3b21ab7f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -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 index 00000000000..eada6779ac3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C @@ -0,0 +1,5 @@ +// PR c++/123080 +// { dg-do compile { target c++20 } } +template struct type_identity { using type = T; }; +auto f = [](auto x) requires requires { typename type_identity::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 index 00000000000..54e72345c9a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires6a.C @@ -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" }