On 12/23/25 5:31 AM, Egas Ribeiro wrote:
Regtested on x86_64-pc-linux-gnu.This patch fixes a few ICEs related to requires-clauses in lambdas like: ``` auto f = [](auto x) requires( auto f = [](auto x) requires(foo;) {} auto f = [](auto x) requires {} {} ``` and many other variations that caused ICEs. However, it doesn't fix the rejects-valid of the testcase from the bug report. The main issue missing is that when we get to grokmethod (and then grokfndecl) we aren't able to create TEMPLATE_INFO for this lambda. I tried a few different fixes but I couldn't stop the call to cp_parser_requires_clause_opt from ruining the template info of this lambda (it is quite shaky when it comes to processing_template_decl).
The problem seems to be that when we try and fail to parse a type-requirement, we hit error recovery code in cp_parser_skip_to_end_of_statement that wants to wrap up the template to recover from the error. But since we're parsing tentatively, that's overkill.
With some changes around the code after grokmethod that attempts to fix the lambda with calls to finish_fully_implicit_template and others (like potentially moving it before grokmethod?), or maybe being able to save some state before calling cp_parser_requires_clause_opt, we might be able to later correctly create TEMPLATE_INFO. Should I open a new BZ for this rejects-valid and associate this patch to that? It's an improvement to having a bunch of ICEs around requires-clauses but doesn't fix PR123080 entirely. -- >8 -- When parsing a lambda with a trailing requires-clause, calling cp_parser_requires_clause_opt really confuses generic lambda parsing when implicit template parameters are involved. This fixes a few ICEs related to invalid/valid requires clauses in lambdas with auto parameters. PR c++/123080 gcc/cp/ChangeLog: * parser.cc (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. Signed-off-by: Egas Ribeiro <[email protected]> --- gcc/cp/parser.cc | 2 ++ gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index b3bf0703d3d..72ff05c20a3 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -12746,6 +12746,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr,if (has_param_list){ + 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.Cnew file mode 100644 index 00000000000..d1f4329a993 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-requires6.C @@ -0,0 +1,6 @@ +// PR c++/123080 +// { dg-do compile { target c++20 } } +// { dg-xfail-if "PR123080 - rejects valid" *-*-* } +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); }
