https://github.com/ahatanak updated 
https://github.com/llvm/llvm-project/pull/138947

>From ece5ba2ee3adac03f058d5cc450ecf2ad70a5a70 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka <ahata...@gmail.com>
Date: Wed, 7 May 2025 12:00:08 -0700
Subject: [PATCH 1/2] [ItaniumMangle] Make sure class types are added to the
 dictionary of substitution candidates when compiling for older ABIs

https://github.com/llvm/llvm-project/pull/132401 made changes to
the function that mangles member pointer types, which caused
substitutions to be mangled incorrectly.

Make sure addSubstitution is called in mangleCXXRecordDecl unless
vtables are being mangled (see https://github.com/llvm/llvm-project/pull/109970
for why that is needed).

rdar://149307496
---
 clang/lib/AST/ItaniumMangle.cpp               | 19 ++++++++++++-------
 .../CodeGenCXX/mangle-itanium-ptrauth.cpp     | 14 ++++++++++++++
 clang/test/CodeGenCXX/mangle.cpp              | 19 ++++++++++++++++---
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 33a8728728574..f5a1c4332ef80 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 IsManglingVTable = false);
   void mangleLambdaSig(const CXXRecordDecl *Lambda);
   void mangleModuleNamePrefix(StringRef Name, bool IsPartition = false);
   void mangleVendorQualifier(StringRef Name);
@@ -3102,11 +3103,15 @@ void CXXNameMangler::mangleType(QualType T) {
     addSubstitution(T);
 }
 
-void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record) {
+void CXXNameMangler::mangleCXXRecordDecl(const CXXRecordDecl *Record,
+                                         bool IsManglingVTable) {
   if (mangleSubstitution(Record))
     return;
   mangleName(Record);
-  if (isCompatibleWith(LangOptions::ClangABI::Ver19))
+  // If we are mangling vtables, return early without adding the record to the
+  // dictionary of substitution candidates to maintain compatibility with older
+  // ABIs.
+  if (IsManglingVTable && isCompatibleWith(LangOptions::ClangABI::Ver19))
     return;
   addSubstitution(Record);
 }
@@ -7501,7 +7506,7 @@ void ItaniumMangleContextImpl::mangleCXXVTable(const 
CXXRecordDecl *RD,
   // <special-name> ::= TV <type>  # virtual table
   CXXNameMangler Mangler(*this, Out);
   Mangler.getStream() << "_ZTV";
-  Mangler.mangleCXXRecordDecl(RD);
+  Mangler.mangleCXXRecordDecl(RD, /*IsManglingVTable=*/true);
 }
 
 void ItaniumMangleContextImpl::mangleCXXVTT(const CXXRecordDecl *RD,
@@ -7509,7 +7514,7 @@ void ItaniumMangleContextImpl::mangleCXXVTT(const 
CXXRecordDecl *RD,
   // <special-name> ::= TT <type>  # VTT structure
   CXXNameMangler Mangler(*this, Out);
   Mangler.getStream() << "_ZTT";
-  Mangler.mangleCXXRecordDecl(RD);
+  Mangler.mangleCXXRecordDecl(RD, /*IsManglingVTable=*/true);
 }
 
 void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
@@ -7519,10 +7524,10 @@ void 
ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
   // <special-name> ::= TC <type> <offset number> _ <base type>
   CXXNameMangler Mangler(*this, Out);
   Mangler.getStream() << "_ZTC";
-  Mangler.mangleCXXRecordDecl(RD);
+  Mangler.mangleCXXRecordDecl(RD, /*IsManglingVTable=*/true);
   Mangler.getStream() << Offset;
   Mangler.getStream() << '_';
-  Mangler.mangleCXXRecordDecl(Type);
+  Mangler.mangleCXXRecordDecl(Type, /*IsManglingVTable=*/true);
 }
 
 void ItaniumMangleContextImpl::mangleCXXRTTI(QualType Ty, raw_ostream &Out) {
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) *) {}
diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp
index f4dc17bc4561e..bf9a4f6187778 100644
--- a/clang/test/CodeGenCXX/mangle.cpp
+++ b/clang/test/CodeGenCXX/mangle.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks 
-std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks 
-std=c++11 | FileCheck --check-prefixes=CHECK,CHECK-ABI-LATEST %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks 
-std=c++11 -fclang-abi-compat=4 | FileCheck %s
 struct X { };
 struct Y { };
 
@@ -1176,7 +1177,7 @@ namespace test56 {
 namespace test57 {
   struct X { template <int N> int f(); } x;
   template<int N> void f(decltype(x.f<0>() + N)) {}
-  // CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fILi0EEET_E
+  // CHECK-ABI-LATEST: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fILi0EEET_E
   template void f<0>(int);
 }
 
@@ -1217,7 +1218,7 @@ namespace test61 {
     };
   };
   template <typename T> void f(typename T::Y::a, typename T::Y::b) {}
-  // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
+  // CHECK-ABI-LATEST-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
   template void f<X>(int, int);
 }
 
@@ -1247,3 +1248,15 @@ namespace test63 {
   // CHECK-LABEL: 
@_ZN6test6312_GLOBAL__N_11fIiEEvNS0_4_AndINS0_17integral_constantIivEENS0_7_OrImplIXsr17integral_constantIT_iEE5valueEEEEE
   void g() { f<int>({}); }
 } // namespace test63
+
+namespace test_substitution {
+struct S { int f(void *, void *); };
+
+typedef int (S::*s_func)(void *, void *);
+
+// clang previously emitted 'S0_' for the second 'void *' parameter type 
because
+// of a bug in the mangler.
+
+// CHECK-LABEL: define void @_ZN17test_substitution4foo1EMNS_1SEFiPvS1_E(
+void foo1(s_func s) {}
+}

>From 1856a6071d2cd64caca725d803151b5f43b8e8b1 Mon Sep 17 00:00:00 2001
From: Akira Hatanaka <ahata...@gmail.com>
Date: Wed, 7 May 2025 17:08:57 -0700
Subject: [PATCH 2/2] Move test to clang-abi-compat.cpp

---
 clang/test/CodeGenCXX/clang-abi-compat.cpp | 12 ++++++++++++
 clang/test/CodeGenCXX/mangle.cpp           | 19 +++----------------
 2 files changed, 15 insertions(+), 16 deletions(-)

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.cpp b/clang/test/CodeGenCXX/mangle.cpp
index bf9a4f6187778..f4dc17bc4561e 100644
--- a/clang/test/CodeGenCXX/mangle.cpp
+++ b/clang/test/CodeGenCXX/mangle.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks 
-std=c++11 | FileCheck --check-prefixes=CHECK,CHECK-ABI-LATEST %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks 
-std=c++11 -fclang-abi-compat=4 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks 
-std=c++11 | FileCheck %s
 struct X { };
 struct Y { };
 
@@ -1177,7 +1176,7 @@ namespace test56 {
 namespace test57 {
   struct X { template <int N> int f(); } x;
   template<int N> void f(decltype(x.f<0>() + N)) {}
-  // CHECK-ABI-LATEST: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fILi0EEET_E
+  // CHECK-LABEL: @_ZN6test571fILi0EEEvDTplcldtL_ZNS_1xEE1fILi0EEET_E
   template void f<0>(int);
 }
 
@@ -1218,7 +1217,7 @@ namespace test61 {
     };
   };
   template <typename T> void f(typename T::Y::a, typename T::Y::b) {}
-  // CHECK-ABI-LATEST-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
+  // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
   template void f<X>(int, int);
 }
 
@@ -1248,15 +1247,3 @@ namespace test63 {
   // CHECK-LABEL: 
@_ZN6test6312_GLOBAL__N_11fIiEEvNS0_4_AndINS0_17integral_constantIivEENS0_7_OrImplIXsr17integral_constantIT_iEE5valueEEEEE
   void g() { f<int>({}); }
 } // namespace test63
-
-namespace test_substitution {
-struct S { int f(void *, void *); };
-
-typedef int (S::*s_func)(void *, void *);
-
-// clang previously emitted 'S0_' for the second 'void *' parameter type 
because
-// of a bug in the mangler.
-
-// CHECK-LABEL: define void @_ZN17test_substitution4foo1EMNS_1SEFiPvS1_E(
-void foo1(s_func s) {}
-}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to