[clang] b035580 - [ItaniumMangle] Make sure class types are added to the dictionary of substitution candidates when compiling for older ABIs (#138947)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 28 11:49:44 PDT 2025
Author: Akira Hatanaka
Date: 2025-05-28T11:49:40-07:00
New Revision: b03558080eda9ebe3955afdd52aed902c5087310
URL: https://github.com/llvm/llvm-project/commit/b03558080eda9ebe3955afdd52aed902c5087310
DIFF: https://github.com/llvm/llvm-project/commit/b03558080eda9ebe3955afdd52aed902c5087310.diff
LOG: [ItaniumMangle] Make sure class types are added to the dictionary of substitution candidates when compiling for older ABIs (#138947)
`mangleCXXRecordDecl` should add class types to the substitution
dictionary unless it is called by `mangleCXXCtorVTable` (see
https://github.com/llvm/llvm-project/pull/109970 for why that is
needed).
This fixes a mis-compile caused by
https://github.com/llvm/llvm-project/pull/132401, which started calling
`mangleCXXRecordDecl` in `CXXNameMangler::mangleType(const
MemberPointerType *T)`.
rdar://149307496
Added:
Modified:
clang/lib/AST/ItaniumMangle.cpp
clang/test/CodeGenCXX/clang-abi-compat.cpp
clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ee51046fd201b..f7c620dc09df7 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -455,7 +455,8 @@ class CXXNameMangler {
void mangleSeqID(unsigned SeqID);
void mangleName(GlobalDecl GD);
void mangleType(QualType T);
- void mangleCXXRecordDecl(const CXXRecordDecl *Record);
+ void mangleCXXRecordDecl(const CXXRecordDecl *Record,
+ bool SuppressSubstitution = false);
void mangleLambdaSig(const CXXRecordDecl *Lambda);
void mangleModuleNamePrefix(StringRef Name, bool IsPartition = false);
void mangleVendorQualifier(StringRef Name);
@@ -3103,11 +3104,12 @@ void CXXNameMangler::mangleType(QualType T) {
addSubstitution(T);
}
-void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
+void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record,
+ bool SuppressSubstitution) {
if (mangleSubstitution(Record))
return;
mangleName(Record);
- if (isCompatibleWith(LangOptions::ClangABI::Ver19))
+ if (SuppressSubstitution)
return;
addSubstitution(Record);
}
@@ -7557,7 +7559,12 @@ void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
// <special-name> ::= TC <type> <offset number> _ <base type>
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTC";
- Mangler.mangleCXXRecordDecl(RD);
+ // Older versions of clang did not add the record as a substitution candidate
+ // here.
+ bool SuppressSubstitution =
+ getASTContext().getLangOpts().getClangABICompat() <=
+ LangOptions::ClangABI::Ver19;
+ Mangler.mangleCXXRecordDecl(RD, SuppressSubstitution);
Mangler.getStream() << Offset;
Mangler.getStream() << '_';
Mangler.mangleCXXRecordDecl(Type);
diff --git a/clang/test/CodeGenCXX/clang-abi-compat.cpp b/clang/test/CodeGenCXX/clang-abi-compat.cpp
index 4d518116f0a70..e23b6f5d59d49 100644
--- a/clang/test/CodeGenCXX/clang-abi-compat.cpp
+++ b/clang/test/CodeGenCXX/clang-abi-compat.cpp
@@ -160,3 +160,15 @@ template <typename T> void test10(typename T::Y::a, typename T::Y::b, float*, fl
// PRE15: @_Z6test10I1XEvNT_1Y1aENS1_1Y1bEPfS4_
// V15: @_Z6test10I1XEvNT_1Y1aENS2_1bEPfS5_
template void test10<X>(int, int, float*, float*);
+
+namespace test_substitution {
+struct S { int f(void *, void *); };
+
+typedef int (S::*s_func)(void *, void *);
+
+// clang used to incorrectly emit 'S0_' for the second 'void *' parameter type
+// when targeting older ABIs because of a bug in the mangler.
+
+// CHECK-LABEL: define dso_local void @_ZN17test_substitution4foo1EMNS_1SEFiPvS1_E(
+void foo1(s_func s) {}
+}
diff --git a/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp b/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp
index 88d80423c3764..155b766803a0a 100644
--- a/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp
+++ b/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp
@@ -1,5 +1,19 @@
// RUN: %clang_cc1 -std=c++11 -fptrauth-intrinsics -fptrauth-calls -emit-llvm -o - -triple=arm64-apple-ios %s | FileCheck %s
// RUN: %clang_cc1 -std=c++11 -fptrauth-intrinsics -fptrauth-calls -emit-llvm -o - -triple=aarch64-linux-gnu %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fptrauth-intrinsics -fptrauth-calls -emit-llvm -o - -triple=arm64-apple-ios -fclang-abi-compat=4 %s | FileCheck %s
+
+// clang previously emitted an incorrect discriminator for the member function
+// pointer because of a bug in the mangler.
+
+// CHECK: @_ZN17test_substitution5funcsE = global [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN17test_substitution1S1fEPvS1_, i32 0, i64 48995) to i64), i64 0 }], align 8
+namespace test_substitution {
+struct S { int f(void *, void *); };
+
+typedef int (S::*s_func)(void *, void *);
+
+s_func funcs[] = { (s_func)(&S::f) };
+}
+
// CHECK: define {{.*}}void @_Z3fooPU9__ptrauthILj3ELb1ELj234EEPi(
void foo(int * __ptrauth(3, 1, 234) *) {}
More information about the cfe-commits
mailing list