r257205 - [MS ABI] Complete and base constructor GlobalDecls must have the same name

David Majnemer via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 8 12:48:26 PST 2016


Author: majnemer
Date: Fri Jan  8 14:48:26 2016
New Revision: 257205

URL: http://llvm.org/viewvc/llvm-project?rev=257205&view=rev
Log:
[MS ABI] Complete and base constructor GlobalDecls must have the same name

Clang got itself into the situation where we mangled the same
constructor twice with two different constructor types.  After one of
the constructors were utilized, the tag used for one of the types
changed from class to struct because a class template became complete.
This resulted in one of the constructor types varying from the other
constructor.

Instead, force "base" constructor types to "complete" if the ABI doesn't
have constructor variants.  This will ensure that GlobalDecls for both
variants will get the same mangled name.

This fixes PR26029.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms.cpp

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=257205&r1=257204&r2=257205&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Jan  8 14:48:26 2016
@@ -615,7 +615,20 @@ void CodeGenModule::setTLSMode(llvm::Glo
 }
 
 StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
-  StringRef &FoundStr = MangledDeclNames[GD.getCanonicalDecl()];
+  GlobalDecl CanonicalGD = GD.getCanonicalDecl();
+
+  // Some ABIs don't have constructor variants.  Make sure that base and
+  // complete constructors get mangled the same.
+  if (const auto *CD = dyn_cast<CXXConstructorDecl>(CanonicalGD.getDecl())) {
+    if (!getTarget().getCXXABI().hasConstructorVariants()) {
+      CXXCtorType OrigCtorType = GD.getCtorType();
+      assert(OrigCtorType == Ctor_Base || OrigCtorType == Ctor_Complete);
+      if (OrigCtorType == Ctor_Base)
+        CanonicalGD = GlobalDecl(CD, Ctor_Complete);
+    }
+  }
+
+  StringRef &FoundStr = MangledDeclNames[CanonicalGD];
   if (!FoundStr.empty())
     return FoundStr;
 

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=257205&r1=257204&r2=257205&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Fri Jan  8 14:48:26 2016
@@ -454,3 +454,28 @@ namespace Complex {
 // CHECK-DAG: define void @"\01?f at Complex@@YAXU?$_Complex at H@__clang@@@Z"(
 void f(_Complex int) {}
 }
+
+namespace PR26029 {
+template <class>
+struct L {
+  L() {}
+};
+template <class>
+class H;
+struct M : L<H<int *> > {};
+
+template <class>
+struct H {};
+
+template <class GT>
+void m_fn3() {
+  (H<GT *>());
+  M();
+}
+
+void runOnFunction() {
+  L<H<int *> > b;
+  m_fn3<int>();
+}
+// CHECK-DAG: call {{.*}} @"\01??0?$L at V?$H at PAH@PR26029@@@PR26029@@QAE at XZ"
+}




More information about the cfe-commits mailing list