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) *) {} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits