]> granicus.if.org Git - clang/commitdiff
[ItaniumCXXABI] Always use linkonce_odr linkage for RTTI data on MinGW
authorMartin Storsjo <martin@martin.st>
Thu, 31 Aug 2017 08:29:59 +0000 (08:29 +0000)
committerMartin Storsjo <martin@martin.st>
Thu, 31 Aug 2017 08:29:59 +0000 (08:29 +0000)
This fixes cases where dynamic classes produced RTTI data with
external linkage, producing linker errors about duplicate symbols.

This touches code close to what was changed in SVN r244266, but
this change doesn't break the tests added in that revision.

Differential revision: https://reviews.llvm.org/D37206

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

lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/rtti-mingw64.cpp

index d78c032cec88a100ba88be6be3402f3b8208480d..e07dbdd3abd0e435c55789a8d16730e768a03bbf 100644 (file)
@@ -2998,15 +2998,13 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
         if (RD->hasAttr<DLLImportAttr>() &&
             ShouldUseExternalRTTIDescriptor(CGM, Ty))
           return llvm::GlobalValue::ExternalLinkage;
-      if (RD->isDynamicClass()) {
-        llvm::GlobalValue::LinkageTypes LT = CGM.getVTableLinkage(RD);
-        // MinGW won't export the RTTI information when there is a key function.
-        // Make sure we emit our own copy instead of attempting to dllimport it.
-        if (RD->hasAttr<DLLImportAttr>() &&
-            llvm::GlobalValue::isAvailableExternallyLinkage(LT))
-          LT = llvm::GlobalValue::LinkOnceODRLinkage;
-        return LT;
-      }
+      // MinGW always uses LinkOnceODRLinkage for type info.
+      if (RD->isDynamicClass() &&
+          !CGM.getContext()
+               .getTargetInfo()
+               .getTriple()
+               .isWindowsGNUEnvironment())
+        return CGM.getVTableLinkage(RD);
     }
 
     return llvm::GlobalValue::LinkOnceODRLinkage;
index 818b11b64bc53f946e9821d1ce0b0d406d8dd8cc..9f3e03961e89184092e7e0d377b4867aa8f3a27e 100644 (file)
@@ -2,7 +2,12 @@
 struct A { int a; };
 struct B : virtual A { int b; };
 B b;
+class C {
+  virtual ~C();
+};
+C::~C() {}
 
+// CHECK: @_ZTI1C = linkonce_odr
 // CHECK: @_ZTI1B = linkonce_odr constant { i8*, i8*, i32, i32, i8*, i64 }
 // CHECK-SAME:  i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*),
 // CHECK-SAME:  i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0),