Bug 103901 - A lambda with a new type in its body cannot be defined inside template parameter list
Summary: A lambda with a new type in its body cannot be defined inside template parame...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: c++-lambda, rejects-valid
Depends on:
Blocks: 101911 lambdas 123550 123566
  Show dependency treegraph
 
Reported: 2022-01-04 08:35 UTC by Fedor Chelnokov
Modified: 2026-04-13 16:46 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-04-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fedor Chelnokov 2022-01-04 08:35:54 UTC
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
Comment 1 Drea Pinski 2022-01-04 18:37:47 UTC
Confirmed.
I thought I had saw a similar bug before.
Comment 2 Drea Pinski 2022-01-04 18:38:49 UTC
(In reply to Andrew Pinski from comment #1)
> I thought I had saw a similar bug before.

I did PR 101911.
Comment 3 Jakub Jelinek 2022-01-04 20:15:30 UTC
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).
Comment 4 GCC Commits 2026-04-13 16:46:47 UTC
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.