The following valid struct template definition: ``` template <auto = []{ struct A{}; }> struct B {}; ``` is accepted by Clang and MSVC, but not by GCC that complains `error: definition of 'struct<lambda()>::A' inside template parameter list`. Demo: https://gcc.godbolt.org/z/f1dxGbPvs Related discussion: https://stackoverflow.com/q/70571380/7325599
Confirmed. I thought I had saw a similar bug before.
(In reply to Andrew Pinski from comment #1) > I thought I had saw a similar bug before. I did PR 101911.
If it is valid, I think e.g. --- gcc/cp/parser.c.jj 2022-01-04 09:59:37.297641779 +0100 +++ gcc/cp/parser.c 2022-01-04 20:56:19.065070397 +0100 @@ -11046,6 +11046,9 @@ cp_parser_lambda_expression (cp_parser* bool save_in_consteval_if_p = in_consteval_if_p; in_consteval_if_p = false; + int saved_processing_template_parmlist = processing_template_parmlist; + processing_template_parmlist = 0; + /* By virtue of defining a local class, a lambda expression has access to the private variables of enclosing classes. */ @@ -11078,6 +11081,7 @@ cp_parser_lambda_expression (cp_parser* in_consteval_if_p = save_in_consteval_if_p; in_discarded_stmt = discarded; + processing_template_parmlist = saved_processing_template_parmlist; parser->num_template_parameter_lists = saved_num_template_parameter_lists; parser->in_statement = in_statement; should fix that. But as the stack-overflow link says, it is unclear. Also, we still reject even with the above patch decltype ([]{ struct A {} ; return 1; }) a; (guess that is PR101911).
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:847fca4bdd58df28260902398670e5010d73725d commit r16-8587-g847fca4bdd58df28260902398670e5010d73725d Author: Jason Merrill <jason@redhat.com> Date: Mon Apr 13 12:46:33 2026 -0400 c++: local class in lambda in default targ [PR123566] Since we started to clear processing_template_parmlist within a lambda, we started to ICE on a local class in such a lambda where previously we would give a (wrong) error. Let's sorry instead of ICE. The failure mode is that in a parmlist current_template_args() is a 0-length TREE_VEC, and so tsubst thinks that the type is not dependent, and returns the type unchanged. We need to overhaul our handling of local classes (and enums) in lambdas so that they are regenerated along with the lamba itself; instantiating them based on the surrounding template parms happens to work in some cases but is generally wrong; see also PR100198. PR c++/103901 PR c++/123566 gcc/cp/ChangeLog: * pt.cc (push_template_decl): Sorry on local class in lambda in template parm list. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ25.C: New test.