]> granicus.if.org Git - clang/commitdiff
[MS ABI] Complete and base constructor GlobalDecls must have the same name
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 8 Jan 2016 20:48:26 +0000 (20:48 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 8 Jan 2016 20:48:26 +0000 (20:48 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@257205 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/mangle-ms.cpp

index 536c55ae4e1810be6174665a2dd761cecfb51faa..97b166278f81b4cb2df2d3483dcf8cc1945e7dd2 100644 (file)
@@ -615,7 +615,20 @@ void CodeGenModule::setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const {
 }
 
 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;
 
index c2a311423a9d1424891c615560497012b115ecba..c82fca49f6136a60e05775571a8a5160bb339d3f 100644 (file)
@@ -454,3 +454,28 @@ namespace Complex {
 // CHECK-DAG: define void @"\01?f@Complex@@YAXU?$_Complex@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@V?$H@PAH@PR26029@@@PR26029@@QAE@XZ"
+}