]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: local class in lambda in default targ [PR123566]
authorJason Merrill <jason@redhat.com>
Mon, 13 Apr 2026 16:46:33 +0000 (12:46 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 13 Apr 2026 16:46:33 +0000 (12:46 -0400)
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.

gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp2a/lambda-targ25.C [new file with mode: 0644]

index 96faac7a2b08dce97850b159c82c4d6358a78d18..cb1a9ab49ae895db938660aac7a7ee22ce3e8898 100644 (file)
@@ -6378,6 +6378,13 @@ push_template_decl (tree decl, bool is_friend)
       if (DECL_TEMPLATE_INFO (tmpl))
        args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
 
+      /* Bug c++/103901.  Let's sorry now rather than ICE later.  */
+      if (TREE_VEC_LENGTH (args) == 0
+         && ctx && LAMBDA_FUNCTION_P (ctx)
+         && DECL_IMPLICIT_TYPEDEF_P (decl)
+         && CLASS_TYPE_P (TREE_TYPE (decl)))
+       sorry ("local class in lambda in template parameter list");
+
       tree info = build_template_info (tmpl, args);
 
       if (DECL_IMPLICIT_TYPEDEF_P (decl))
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ25.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ25.C
new file mode 100644 (file)
index 0000000..3bd189f
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/123566
+// { dg-do compile { target c++20 } }
+
+template <class T, auto =
+              [] {
+                struct { // { dg-bogus "local class" "PR103901" { xfail *-*-* } }
+                } s;    // We would ICE trying to call the constructor.
+              }>
+bool v;
+auto x = v<int>;