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>
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)
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);
--- /dev/null
+// 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); }
--- /dev/null
+// PR c++/123080
+// { dg-do compile { target c++20 } }
+auto f = [](auto x) requires requires { // { dg-error "expected | invalid member template | constraints" }