[clang] [Clang] Fix the mangling of lambdas (PR #89204)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 18 08:20:23 PDT 2024
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/89204
>From 6382171fbd2075f1f0f3484bfde9ad96ec878f6e Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 18 Apr 2024 12:19:41 +0200
Subject: [PATCH 1/3] [Clang] Fix the mangling of lambdas
Lambdas used in the initializer of a local class were not mangling
the name of the member.
Fixes #88906
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/AST/ItaniumMangle.cpp | 18 ++++++-------
.../CodeGenCXX/mangle-lambdas-gh88906.cpp | 27 +++++++++++++++++++
3 files changed, 36 insertions(+), 10 deletions(-)
create mode 100644 clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6c51c2d1f483ce..0ad301b24e6b73 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -538,6 +538,7 @@ Bug Fixes to C++ Support
- Fix a crash in requires expression with templated base class member function. Fixes (#GH84020).
- Fix a crash caused by defined struct in a type alias template when the structure
has fields with dependent type. Fixes (#GH75221).
+- Fix the Itanium mangling of lambdas defined in a member of a local class (#GH88906)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index c3b98d2d2149cb..53ef022c710d8d 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -1070,14 +1070,7 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
if (isLocalContainerContext(DC) && ND->hasLinkage() && !isLambda(ND))
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = Context.getEffectiveParentContext(DC);
- else if (GetLocalClassDecl(ND)) {
- mangleLocalName(GD, AdditionalAbiTags);
- return;
- }
-
- assert(!isa<LinkageSpecDecl>(DC) && "context cannot be LinkageSpecDecl");
-
- if (isLocalContainerContext(DC)) {
+ else if (GetLocalClassDecl(ND) && !isLambda(ND)) {
mangleLocalName(GD, AdditionalAbiTags);
return;
}
@@ -1089,6 +1082,13 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
return;
}
+ assert(!isa<LinkageSpecDecl>(DC) && "context cannot be LinkageSpecDecl");
+
+ if (isLocalContainerContext(DC)) {
+ mangleLocalName(GD, AdditionalAbiTags);
+ return;
+ }
+
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
// Check if we have a template.
const TemplateArgumentList *TemplateArgs = nullptr;
@@ -2201,8 +2201,6 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
if (NoFunction && isLocalContainerContext(DC))
return;
- assert(!isLocalContainerContext(DC));
-
const NamedDecl *ND = cast<NamedDecl>(DC);
if (mangleSubstitution(ND))
return;
diff --git a/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
new file mode 100644
index 00000000000000..61f340c848ebe4
--- /dev/null
+++ b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -o - | FileCheck %s
+
+class func {
+public:
+ template <typename T>
+ func(T){};
+ template <typename T, typename U>
+ func(T, U){};
+};
+
+void GH88906(){
+ class Test{
+ public:
+ func a{[]{ }, []{ }};
+ func b{[]{ }};
+ func c{[]{ }};
+ } test;
+}
+
+// CHECK-LABEL: define internal void @_ZZ7GH88906vEN4TestC2Ev
+// CHECK: call void @_ZN4funcC2IN7GH889064Test1aMUlvE_ENS3_UlvE0_EEET_T0_
+// CHECK: call void @_ZN4funcC2IN7GH889064Test1bMUlvE_EEET_
+// CHECK: call void @_ZN4funcC2IN7GH889064Test1cMUlvE_EEET_
+
+// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1aMUlvE_ENS3_UlvE0_EEET_T0_
+// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1bMUlvE_EEET_
+// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1cMUlvE_EEET_
>From 4e7b7762fcb74e93e60a380c3b7693f3e2c94673 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 18 Apr 2024 14:58:19 +0200
Subject: [PATCH 2/3] ms abi tests
---
clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
index 61f340c848ebe4..d3f9f269d4c3ab 100644
--- a/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
+++ b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck --check-prefix=MSABI %s
+
class func {
public:
@@ -25,3 +27,14 @@ void GH88906(){
// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1aMUlvE_ENS3_UlvE0_EEET_T0_
// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1bMUlvE_EEET_
// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1cMUlvE_EEET_
+
+
+
+// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??0Test@?1??GH88906@@YAXXZ at QAE@XZ"
+// MSABI: call x86_thiscallcc noundef ptr @"??$?0V<lambda_1>@a at Test@?1??GH88906@@YAXXZ at V<lambda_2>@12?1??3 at YAXXZ@@func@@QAE at V<lambda_1>@a at Test@?1??GH88906@@YAXXZ at V<lambda_2>@23?1??4 at YAXXZ@@Z"
+// MSABI: call x86_thiscallcc noundef ptr @"??$?0V<lambda_1>@b at Test@?1??GH88906@@YAXXZ@@func@@QAE at V<lambda_1>@b at Test@?1??GH88906@@YAXXZ@@Z"
+// MSABI: call x86_thiscallcc noundef ptr @"??$?0V<lambda_1>@c at Test@?1??GH88906@@YAXXZ@@func@@QAE at V<lambda_1>@c at Test@?1??GH88906@@YAXXZ@@Z"
+
+// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??$?0V<lambda_1>@a at Test@?1??GH88906@@YAXXZ at V<lambda_2>@12?1??3 at YAXXZ@@func@@QAE at V<lambda_1>@a at Test@?1??GH88906@@YAXXZ at V<lambda_2>@23?1??4 at YAXXZ@@Z"
+// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??$?0V<lambda_1>@b at Test@?1??GH88906@@YAXXZ@@func@@QAE at V<lambda_1>@b at Test@?1??GH88906@@YAXXZ@@Z"
+// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??$?0V<lambda_1>@c at Test@?1??GH88906@@YAXXZ@@func@@QAE at V<lambda_1>@c at Test@?1??GH88906@@YAXXZ@@Z"
>From 1a454e2d5108005440be27844a1b8ea805b798e8 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 18 Apr 2024 17:20:06 +0200
Subject: [PATCH 3/3] Add ABI tag
---
clang/include/clang/Basic/LangOptions.h | 5 +++++
clang/lib/AST/ItaniumMangle.cpp | 10 ++++++----
clang/lib/Frontend/CompilerInvocation.cpp | 5 +++++
clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp | 10 ++++++++--
4 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 24b109e32cdd3e..75562284ec7de0 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -224,6 +224,11 @@ class LangOptionsBase {
/// - the parameter list of a template template parameter
Ver17,
+ /// Attempt to be ABI-compatible with code generated by Clang 18.0.x.
+ /// This causes clang to revert some fixes to the mangling of lambdas
+ /// in the initializers of members of local classes.
+ Ver18,
+
/// Conform to the underlying platform's C and C++ ABIs as closely
/// as we can.
Latest
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 53ef022c710d8d..106c69dd5beed7 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -1062,19 +1062,23 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
// ::= <local-name>
//
const DeclContext *DC = Context.getEffectiveDeclContext(ND);
+ bool IsLambda = isLambda(ND);
// If this is an extern variable declared locally, the relevant DeclContext
// is that of the containing namespace, or the translation unit.
// FIXME: This is a hack; extern variables declared locally should have
// a proper semantic declaration context!
- if (isLocalContainerContext(DC) && ND->hasLinkage() && !isLambda(ND))
+ if (isLocalContainerContext(DC) && ND->hasLinkage() && !IsLambda)
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = Context.getEffectiveParentContext(DC);
- else if (GetLocalClassDecl(ND) && !isLambda(ND)) {
+ else if (GetLocalClassDecl(ND) &&
+ (!IsLambda || isCompatibleWith(LangOptions::ClangABI::Ver18))) {
mangleLocalName(GD, AdditionalAbiTags);
return;
}
+ assert(!isa<LinkageSpecDecl>(DC) && "context cannot be LinkageSpecDecl");
+
// Closures can require a nested-name mangling even if they're semantically
// in the global namespace.
if (const NamedDecl *PrefixND = getClosurePrefix(ND)) {
@@ -1082,8 +1086,6 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
return;
}
- assert(!isa<LinkageSpecDecl>(DC) && "context cannot be LinkageSpecDecl");
-
if (isLocalContainerContext(DC)) {
mangleLocalName(GD, AdditionalAbiTags);
return;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 1f1f5440ddd75f..c689e7afde0982 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3655,6 +3655,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
case LangOptions::ClangABI::Ver17:
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");
break;
+ case LangOptions::ClangABI::Ver18:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
+ break;
case LangOptions::ClangABI::Latest:
break;
}
@@ -4162,6 +4165,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
else if (Major <= 17)
Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
+ else if (Major <= 18)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
diff --git a/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
index d3f9f269d4c3ab..e7592cec5da776 100644
--- a/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
+++ b/clang/test/CodeGenCXX/mangle-lambdas-gh88906.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck --check-prefix=MSABI %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -emit-llvm -mconstructor-aliases -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fclang-abi-compat=18 %s -emit-llvm -mconstructor-aliases -o - | FileCheck --check-prefix=CLANG18 %s
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -mconstructor-aliases -o - | FileCheck --check-prefix=MSABI %s
class func {
@@ -28,6 +29,11 @@ void GH88906(){
// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1bMUlvE_EEET_
// CHECK-LABEL: define internal void @_ZN4funcC2IN7GH889064Test1cMUlvE_EEET_
+// CLANG18-LABEL: define internal void @_ZZ7GH88906vEN4TestC2Ev
+// CLANG18: call void @_ZN4funcC2IZ7GH88906vEN4TestUlvE_EZ7GH88906vENS1_UlvE0_EEET_T0_
+// CLANG18: call void @_ZN4funcC2IZ7GH88906vEN4TestUlvE_EEET_
+// CLANG18: call void @_ZN4funcC2IZ7GH88906vEN4TestUlvE_EEET_
+
// MSABI-LABEL: define internal x86_thiscallcc noundef ptr @"??0Test@?1??GH88906@@YAXXZ at QAE@XZ"
More information about the cfe-commits
mailing list