]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++/modules: Treat unattached lambdas as TU-local [PR116568]
authorNathaniel Shead <nathanieloshead@gmail.com>
Sun, 5 Jan 2025 12:01:44 +0000 (23:01 +1100)
committerNathaniel Shead <nathanieloshead@gmail.com>
Sat, 25 Jan 2025 00:36:10 +0000 (11:36 +1100)
This fixes ICEs where unattached lambdas at class scope (for instance,
in member template instantiations) are streamed.  This is only possible
in header units, as in named modules attempting to stream such lambdas
will be an error.

PR c++/116568

gcc/cp/ChangeLog:

* module.cc (trees_out::get_merge_kind): Treat all lambdas
without a mangling scope as un-mergeable.

gcc/testsuite/ChangeLog:

* g++.dg/modules/lambda-8.h: New test.
* g++.dg/modules/lambda-8_a.H: New test.
* g++.dg/modules/lambda-8_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/lambda-8.h [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/lambda-8_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/lambda-8_b.C [new file with mode: 0644]

index 1c1eb2e37e2dc1ac684c02834c8a00c513b84d7c..c89834c1abdf81e7dba9491cfcc36676e4cc6025 100644 (file)
@@ -11014,18 +11014,23 @@ trees_out::get_merge_kind (tree decl, depset *dep)
               g++.dg/modules/lambda-6_a.C.  */
            if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl))
                && LAMBDA_TYPE_P (TREE_TYPE (decl)))
-             if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)))
-               {
-                 /* Lambdas attached to fields are keyed to its class.  */
-                 if (TREE_CODE (scope) == FIELD_DECL)
-                   scope = TYPE_NAME (DECL_CONTEXT (scope));
-                 if (DECL_LANG_SPECIFIC (scope)
-                     && DECL_MODULE_KEYED_DECLS_P (scope))
-                   {
-                     mk = MK_keyed;
-                     break;
-                   }
-               }
+             {
+               if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)))
+                 {
+                   /* Lambdas attached to fields are keyed to its class.  */
+                   if (TREE_CODE (scope) == FIELD_DECL)
+                     scope = TYPE_NAME (DECL_CONTEXT (scope));
+                   if (DECL_LANG_SPECIFIC (scope)
+                       && DECL_MODULE_KEYED_DECLS_P (scope))
+                     {
+                       mk = MK_keyed;
+                       break;
+                     }
+                 }
+               /* Lambdas not attached to any mangling scope are TU-local.  */
+               mk = MK_unique;
+               break;
+             }
 
            if (TREE_CODE (decl) == TEMPLATE_DECL
                && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (decl))
diff --git a/gcc/testsuite/g++.dg/modules/lambda-8.h b/gcc/testsuite/g++.dg/modules/lambda-8.h
new file mode 100644 (file)
index 0000000..c4bb20d
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/116568
+
+template <typename> struct S {
+  template <typename> using t = decltype([]{});
+};
+
+// 't' does not currently have a mangling scope, but should not ICE
+using t = S<int>::t<int>;
diff --git a/gcc/testsuite/g++.dg/modules/lambda-8_a.H b/gcc/testsuite/g++.dg/modules/lambda-8_a.H
new file mode 100644 (file)
index 0000000..d20958e
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/116568
+// { dg-additional-options "-fmodules-ts -std=c++20" }
+// { dg-module-cmi {} }
+
+#include "lambda-8.h"
diff --git a/gcc/testsuite/g++.dg/modules/lambda-8_b.C b/gcc/testsuite/g++.dg/modules/lambda-8_b.C
new file mode 100644 (file)
index 0000000..7ace494
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/116568
+// { dg-additional-options "-fmodules-ts -fno-module-lazy -std=c++20" }
+
+#include "lambda-8.h"
+import "lambda-8_a.H";
+
+// { dg-error "conflicting global module declaration" "" { target *-*-* } 0 }