[clang] 7883b02 - [ItaniumMangle] Add substitutions for record types when mangling vtables (#109970)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 28 20:43:31 PDT 2024
Author: tcwzxx
Date: 2024-09-29T11:43:28+08:00
New Revision: 7883b028b42df7b763cae20d8ff56233bee4beb6
URL: https://github.com/llvm/llvm-project/commit/7883b028b42df7b763cae20d8ff56233bee4beb6
DIFF: https://github.com/llvm/llvm-project/commit/7883b028b42df7b763cae20d8ff56233bee4beb6.diff
LOG: [ItaniumMangle] Add substitutions for record types when mangling vtables (#109970)
Fix #108015
The `mangleNameOrStandardSubstitution` function does not add the RD type
into the substitution, which causes the mangling of the \<base type\> to
be incorrect.
Rename `mangleNameOrStandardSubstitution` to `mangleCXXRecordDecl` and add `Record` as a substitution
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/LangOptions.h
clang/lib/AST/ItaniumMangle.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/CodeGenCXX/mangle-subst.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2e9560f553d94f..28c759538f7df6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -103,6 +103,7 @@ ABI Changes in This Version
---------------------------
- Fixed Microsoft name mangling of placeholder, auto and decltype(auto), return types for MSVC 1920+. This change resolves incompatibilities with code compiled by MSVC 1920+ but will introduce incompatibilities with code compiled by earlier versions of Clang unless such code is built with the compiler option -fms-compatibility-version=19.14 to imitate the MSVC 1914 mangling behavior.
+- Fixed the Itanium mangling of the construction vtable name. This change will introduce incompatibilities with code compiled by Clang 19 and earlier versions, unless the -fclang-abi-compat=19 option is used. (#GH108015)
AST Dumping Potentially Breaking Changes
----------------------------------------
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index c3d53ca92d450c..8c605f6852016e 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -239,6 +239,12 @@ class LangOptionsBase {
/// in the initializers of members of local classes.
Ver18,
+ /// Attempt to be ABI-compatible with code generated by Clang 19.0.x.
+ /// This causes clang to:
+ /// - Incorrectly mangles the 'base type' substitutions of the CXX
+ /// construction vtable because it hasn't added 'type' as a substitution.
+ Ver19,
+
/// 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 b6e1da0c3192da..f043da23ff1680 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -464,7 +464,7 @@ class CXXNameMangler {
void mangleSeqID(unsigned SeqID);
void mangleName(GlobalDecl GD);
void mangleType(QualType T);
- void mangleNameOrStandardSubstitution(const NamedDecl *ND);
+ void mangleCXXRecordDecl(const CXXRecordDecl *Record);
void mangleLambdaSig(const CXXRecordDecl *Lambda);
void mangleModuleNamePrefix(StringRef Name, bool IsPartition = false);
void mangleVendorQualifier(StringRef Name);
@@ -3029,9 +3029,13 @@ void CXXNameMangler::mangleType(QualType T) {
addSubstitution(T);
}
-void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
- if (!mangleStandardSubstitution(ND))
- mangleName(ND);
+void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
+ if (mangleSubstitution(Record))
+ return;
+ mangleName(Record);
+ if (isCompatibleWith(LangOptions::ClangABI::Ver19))
+ return;
+ addSubstitution(Record);
}
void CXXNameMangler::mangleType(const BuiltinType *T) {
@@ -7309,7 +7313,7 @@ void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD,
// <special-name> ::= TV <type> # virtual table
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTV";
- Mangler.mangleNameOrStandardSubstitution(RD);
+ Mangler.mangleCXXRecordDecl(RD);
}
void ItaniumMangleContextImpl::mangleCXXVTT(const CXXRecordDecl *RD,
@@ -7317,7 +7321,7 @@ void ItaniumMangleContextImpl::mangleCXXVTT(const CXXRecordDecl *RD,
// <special-name> ::= TT <type> # VTT structure
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTT";
- Mangler.mangleNameOrStandardSubstitution(RD);
+ Mangler.mangleCXXRecordDecl(RD);
}
void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
@@ -7327,10 +7331,10 @@ void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
// <special-name> ::= TC <type> <offset number> _ <base type>
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTC";
- Mangler.mangleNameOrStandardSubstitution(RD);
+ Mangler.mangleCXXRecordDecl(RD);
Mangler.getStream() << Offset;
Mangler.getStream() << '_';
- Mangler.mangleNameOrStandardSubstitution(Type);
+ Mangler.mangleCXXRecordDecl(Type);
}
void ItaniumMangleContextImpl::mangleCXXRTTI(QualType Ty, raw_ostream &Out) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 6c09843a7146f4..a0291ccfea2458 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3830,6 +3830,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
case LangOptions::ClangABI::Ver18:
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
break;
+ case LangOptions::ClangABI::Ver19:
+ GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0");
+ break;
case LangOptions::ClangABI::Latest:
break;
}
@@ -4372,6 +4375,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
else if (Major <= 18)
Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
+ else if (Major <= 19)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver19);
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
diff --git a/clang/test/CodeGenCXX/mangle-subst.cpp b/clang/test/CodeGenCXX/mangle-subst.cpp
index 20f33a72fff830..524e0febe479a8 100644
--- a/clang/test/CodeGenCXX/mangle-subst.cpp
+++ b/clang/test/CodeGenCXX/mangle-subst.cpp
@@ -1,4 +1,8 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fclang-abi-compat=19 | FileCheck %s --check-prefix=CHECK-CLANG-19
+
+//CHECK: @_ZTCN16MangleCtorVTable4InstE0_NS_1A4ImplINS1_4WrapEEE
+//CHECK-CLANG-19: @_ZTCN16MangleCtorVTable4InstE0_NS_1A4ImplINS0_4WrapEEE
struct X {};
@@ -96,3 +100,26 @@ typename X<T>::template Y<T>::type f(typename X<T>::template Y<T>::type2) { retu
// CHECK: @_ZN12ManglePrefix1fIiEENS_1XIT_E1YIS2_E4typeENS5_5type2E
template int f<int>(int);
}
+
+namespace MangleCtorVTable {
+namespace A {
+
+class VBase {
+ public:
+ virtual ~VBase() {};
+};
+
+struct Wrap {};
+
+template <typename T>
+class Impl : public virtual VBase {
+ public:
+};
+
+} // namespace A
+
+struct Inst : public A::Impl<A::Wrap> {};
+
+void Test() { Inst a; }
+
+}
More information about the cfe-commits
mailing list