Author: Chuanqi Xu
Date: 2025-12-19T15:44:34+08:00
New Revision: 5937d7f907ef656abb16622c8b4e72fe906e9328

URL: 
https://github.com/llvm/llvm-project/commit/5937d7f907ef656abb16622c8b4e72fe906e9328
DIFF: 
https://github.com/llvm/llvm-project/commit/5937d7f907ef656abb16622c8b4e72fe906e9328.diff

LOG: [C++20] [Modules] Correct the behavior for adding mangling for lambda in 
modules

Close https://github.com/llvm/llvm-project/issues/130080
Close https://github.com/llvm/llvm-project/issues/116087

The common pattern of the problem is the lambda is somehow leaked from a
non-inline non-internal function in module purview, and we need to
define a mangling for it by the discuss from
https://github.com/itanium-cxx-abi/cxx-abi/issues/186

The root cause of the issue is a mismatch that give up too quickly when
ManglingContextDecl is nullptr. But we can still get the context
information from DC.

Added: 
    clang/test/Modules/lambda-convertablity.cppm

Modified: 
    clang/lib/Sema/SemaLambda.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index f65c55a209622..81ec0b18dedfd 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -298,22 +298,23 @@ Sema::getCurrentMangleNumberContext(const DeclContext 
*DC) {
   // definition, as well as the initializers of data members, receive special
   // treatment. Identify them.
   Kind = [&]() {
-    if (!ManglingContextDecl)
-      return Normal;
-
-    if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDecl)) {
+    if (auto *ND = dyn_cast<NamedDecl>(ManglingContextDecl ? 
ManglingContextDecl
+                                                           : cast<Decl>(DC))) {
       // See discussion in 
https://github.com/itanium-cxx-abi/cxx-abi/issues/186
       //
       // zygoloid:
       //    Yeah, I think the only cases left where lambdas don't need a
       //    mangling are when they have (effectively) internal linkage or 
appear
       //    in a non-inline function in a non-module translation unit.
-      Module *M = ManglingContextDecl->getOwningModule();
+      Module *M = ND->getOwningModule();
       if (M && M->getTopLevelModule()->isNamedModuleUnit() &&
           ND->isExternallyVisible())
         return NonInlineInModulePurview;
     }
 
+    if (!ManglingContextDecl)
+      return Normal;
+
     if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) {
       if (const DeclContext *LexicalDC
           = Param->getDeclContext()->getLexicalParent())

diff  --git a/clang/test/Modules/lambda-convertablity.cppm 
b/clang/test/Modules/lambda-convertablity.cppm
new file mode 100644
index 0000000000000..abf20e73531c5
--- /dev/null
+++ b/clang/test/Modules/lambda-convertablity.cppm
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -fprebuilt-module-path=%t 
-fsyntax-only -verify
+//
+// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-reduced-module-interface -o 
%t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/B.cppm -fprebuilt-module-path=%t 
-fsyntax-only -verify
+
+//--- A.cppm
+export module a;
+
+export auto f() {
+    return [](){};
+}
+
+//--- B.cppm
+// expected-no-diagnostics
+export module b;
+import a;
+
+static_assert(__is_convertible_to(decltype(f()), decltype(f())));


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to