[PATCH] D24704: PR30401: Fix substitutions for functions with abi_tag

Dmitry Polukhin via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 18 01:08:40 PDT 2016


DmitryPolukhin created this revision.
DmitryPolukhin added a reviewer: rsmith.
DmitryPolukhin added subscribers: cfe-commits, andreybokhanko.

Recursive mangling should use all existing substitutions and newly created substitutions should be copied outer mangler.

This patch should fix PR30401 and related cases but unfortunately it is ABI breaking change for Clang backward compatibility (I hope it is rare case in practice). Perhaps this patch will have to be back ported to 3.9.

https://reviews.llvm.org/D24704

Files:
  lib/AST/ItaniumMangle.cpp
  test/CodeGenCXX/mangle-abi-tag.cpp

Index: test/CodeGenCXX/mangle-abi-tag.cpp
===================================================================
--- test/CodeGenCXX/mangle-abi-tag.cpp
+++ test/CodeGenCXX/mangle-abi-tag.cpp
@@ -203,3 +203,19 @@
 }
 // A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice!
 // CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv(
+
+namespace N19 {
+  class A {};
+  class __attribute__((abi_tag("B"))) B {};
+  class D {};
+  class F {};
+
+  template<typename T, B F(T, D)>
+  class C {};
+
+  B foo(A, D);
+}
+void f19_test(N19::C<N19::A,  &N19::foo>, N19::F, N19::D) {
+}
+// f19_test(N19::C<N19::A, &N19::foo[abi:B]>, N19::F, N19::D)
+// CHECK-DAG: define void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_(
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -405,12 +405,14 @@
   CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)
       : Context(Outer.Context), Out(Out_), NullOut(false),
         Structor(Outer.Structor), StructorType(Outer.StructorType),
-        SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}
+        SeqID(Outer.SeqID), AbiTagsRoot(AbiTags),
+        Substitutions(Outer.Substitutions) {}
 
   CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_)
       : Context(Outer.Context), Out(Out_), NullOut(true),
         Structor(Outer.Structor), StructorType(Outer.StructorType),
-        SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {}
+        SeqID(Outer.SeqID), AbiTagsRoot(AbiTags),
+        Substitutions(Outer.Substitutions) {}
 
 #if MANGLE_CHECKER
   ~CXXNameMangler() {
@@ -458,6 +460,7 @@
   void addSubstitution(QualType T);
   void addSubstitution(TemplateName Template);
   void addSubstitution(uintptr_t Ptr);
+  void extendSubstitutions(const CXXNameMangler& Other);
 
   void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
                               bool recursive = false);
@@ -685,6 +688,10 @@
   // Output name with implicit tags and function encoding from temporary buffer.
   mangleNameWithAbiTags(FD, &AdditionalAbiTags);
   Out << FunctionEncodingStream.str().substr(EncodingPositionStart);
+
+  // Function encoding could create new substitutions so we have to add
+  // temp mangled substitutions to main mangler.
+  extendSubstitutions(FunctionEncodingMangler);
 }
 
 void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
@@ -4426,6 +4433,14 @@
   Substitutions[Ptr] = SeqID++;
 }
 
+void CXXNameMangler::extendSubstitutions(const CXXNameMangler& Other) {
+  assert(Other.SeqID >= SeqID && "Must be superset of substitutions!");
+  if (Other.SeqID > SeqID) {
+    Substitutions = Other.Substitutions;
+    SeqID = Other.SeqID;
+  }
+}
+
 CXXNameMangler::AbiTagList
 CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) {
   // When derived abi tags are disabled there is no need to make any list.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24704.71742.patch
Type: text/x-patch
Size: 2963 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160918/bdd4cb02/attachment.bin>


More information about the cfe-commits mailing list