https://gcc.gnu.org/g:80bd9eb48190f3554c4de74ccb3d0976831160b1

commit r15-7204-g80bd9eb48190f3554c4de74ccb3d0976831160b1
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Sun Jan 5 23:01:44 2025 +1100

    c++/modules: Treat unattached lambdas as TU-local [PR116568]
    
    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 <nathanielosh...@gmail.com>
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/module.cc                          | 29 +++++++++++++++++------------
 gcc/testsuite/g++.dg/modules/lambda-8.h   |  8 ++++++++
 gcc/testsuite/g++.dg/modules/lambda-8_a.H |  5 +++++
 gcc/testsuite/g++.dg/modules/lambda-8_b.C |  7 +++++++
 4 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 1c1eb2e37e2d..c89834c1abdf 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -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
index 000000000000..c4bb20dcf1f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-8.h
@@ -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
index 000000000000..d20958ee140f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-8_a.H
@@ -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
index 000000000000..7ace4944dd2d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lambda-8_b.C
@@ -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 }

Reply via email to