Skip to content

Commit 7883b02

Browse files
authored
[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
1 parent b0fc36d commit 7883b02

File tree

5 files changed

+51
-8
lines changed

5 files changed

+51
-8
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ ABI Changes in This Version
103103
---------------------------
104104

105105
- 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.
106+
- 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)
106107

107108
AST Dumping Potentially Breaking Changes
108109
----------------------------------------

clang/include/clang/Basic/LangOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ class LangOptionsBase {
239239
/// in the initializers of members of local classes.
240240
Ver18,
241241

242+
/// Attempt to be ABI-compatible with code generated by Clang 19.0.x.
243+
/// This causes clang to:
244+
/// - Incorrectly mangles the 'base type' substitutions of the CXX
245+
/// construction vtable because it hasn't added 'type' as a substitution.
246+
Ver19,
247+
242248
/// Conform to the underlying platform's C and C++ ABIs as closely
243249
/// as we can.
244250
Latest

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ class CXXNameMangler {
464464
void mangleSeqID(unsigned SeqID);
465465
void mangleName(GlobalDecl GD);
466466
void mangleType(QualType T);
467-
void mangleNameOrStandardSubstitution(const NamedDecl *ND);
467+
void mangleCXXRecordDecl(const CXXRecordDecl *Record);
468468
void mangleLambdaSig(const CXXRecordDecl *Lambda);
469469
void mangleModuleNamePrefix(StringRef Name, bool IsPartition = false);
470470
void mangleVendorQualifier(StringRef Name);
@@ -3029,9 +3029,13 @@ void CXXNameMangler::mangleType(QualType T) {
30293029
addSubstitution(T);
30303030
}
30313031

3032-
void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
3033-
if (!mangleStandardSubstitution(ND))
3034-
mangleName(ND);
3032+
void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
3033+
if (mangleSubstitution(Record))
3034+
return;
3035+
mangleName(Record);
3036+
if (isCompatibleWith(LangOptions::ClangABI::Ver19))
3037+
return;
3038+
addSubstitution(Record);
30353039
}
30363040

30373041
void CXXNameMangler::mangleType(const BuiltinType *T) {
@@ -7309,15 +7313,15 @@ void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD,
73097313
// <special-name> ::= TV <type> # virtual table
73107314
CXXNameMangler Mangler(*this, Out);
73117315
Mangler.getStream() << "_ZTV";
7312-
Mangler.mangleNameOrStandardSubstitution(RD);
7316+
Mangler.mangleCXXRecordDecl(RD);
73137317
}
73147318

73157319
void ItaniumMangleContextImpl::mangleCXXVTT(const CXXRecordDecl *RD,
73167320
raw_ostream &Out) {
73177321
// <special-name> ::= TT <type> # VTT structure
73187322
CXXNameMangler Mangler(*this, Out);
73197323
Mangler.getStream() << "_ZTT";
7320-
Mangler.mangleNameOrStandardSubstitution(RD);
7324+
Mangler.mangleCXXRecordDecl(RD);
73217325
}
73227326

73237327
void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
@@ -7327,10 +7331,10 @@ void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
73277331
// <special-name> ::= TC <type> <offset number> _ <base type>
73287332
CXXNameMangler Mangler(*this, Out);
73297333
Mangler.getStream() << "_ZTC";
7330-
Mangler.mangleNameOrStandardSubstitution(RD);
7334+
Mangler.mangleCXXRecordDecl(RD);
73317335
Mangler.getStream() << Offset;
73327336
Mangler.getStream() << '_';
7333-
Mangler.mangleNameOrStandardSubstitution(Type);
7337+
Mangler.mangleCXXRecordDecl(Type);
73347338
}
73357339

73367340
void ItaniumMangleContextImpl::mangleCXXRTTI(QualType Ty, raw_ostream &Out) {

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3830,6 +3830,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
38303830
case LangOptions::ClangABI::Ver18:
38313831
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
38323832
break;
3833+
case LangOptions::ClangABI::Ver19:
3834+
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0");
3835+
break;
38333836
case LangOptions::ClangABI::Latest:
38343837
break;
38353838
}
@@ -4372,6 +4375,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
43724375
Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
43734376
else if (Major <= 18)
43744377
Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
4378+
else if (Major <= 19)
4379+
Opts.setClangABICompat(LangOptions::ClangABI::Ver19);
43754380
} else if (Ver != "latest") {
43764381
Diags.Report(diag::err_drv_invalid_value)
43774382
<< A->getAsString(Args) << A->getValue();

clang/test/CodeGenCXX/mangle-subst.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s
2+
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fclang-abi-compat=19 | FileCheck %s --check-prefix=CHECK-CLANG-19
3+
4+
//CHECK: @_ZTCN16MangleCtorVTable4InstE0_NS_1A4ImplINS1_4WrapEEE
5+
//CHECK-CLANG-19: @_ZTCN16MangleCtorVTable4InstE0_NS_1A4ImplINS0_4WrapEEE
26

37
struct X {};
48

@@ -96,3 +100,26 @@ typename X<T>::template Y<T>::type f(typename X<T>::template Y<T>::type2) { retu
96100
// CHECK: @_ZN12ManglePrefix1fIiEENS_1XIT_E1YIS2_E4typeENS5_5type2E
97101
template int f<int>(int);
98102
}
103+
104+
namespace MangleCtorVTable {
105+
namespace A {
106+
107+
class VBase {
108+
public:
109+
virtual ~VBase() {};
110+
};
111+
112+
struct Wrap {};
113+
114+
template <typename T>
115+
class Impl : public virtual VBase {
116+
public:
117+
};
118+
119+
} // namespace A
120+
121+
struct Inst : public A::Impl<A::Wrap> {};
122+
123+
void Test() { Inst a; }
124+
125+
}

0 commit comments

Comments
 (0)