mstorsjo created this revision.

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.

I have to admit that I have little clue about what I'm doing here and I'm not 
sure if the exact fix is correct (it feels very heavy handed).

Hopefully the testcase shows what this fixes at least; this fixes linker errors 
with pretty trivial setups, where one object file contains the definition of a 
class with a virtual method (making the class dynamic, which previously meant 
that the typeinfo was emitted with external linkage) and another object file 
references typeid(ThatClass) (which produced a linkonce_odr version of that 
class' typeinfo).


https://reviews.llvm.org/D37206

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


Index: test/CodeGenCXX/rtti-mingw64.cpp
===================================================================
--- test/CodeGenCXX/rtti-mingw64.cpp
+++ test/CodeGenCXX/rtti-mingw64.cpp
@@ -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),
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -2987,15 +2987,13 @@
         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;
-      }
+      bool IsMinGW =
+          CGM.getContext().getTargetInfo().getTriple().getEnvironment() ==
+              llvm::Triple::GNU &&
+          CGM.getContext().getTargetInfo().getTriple().isOSWindows();
+      // MinGW always uses LinkOnceODRLinkage for type info.
+      if (RD->isDynamicClass() && !IsMinGW)
+        return CGM.getVTableLinkage(RD);
     }
 
     return llvm::GlobalValue::LinkOnceODRLinkage;


Index: test/CodeGenCXX/rtti-mingw64.cpp
===================================================================
--- test/CodeGenCXX/rtti-mingw64.cpp
+++ test/CodeGenCXX/rtti-mingw64.cpp
@@ -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),
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -2987,15 +2987,13 @@
         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;
-      }
+      bool IsMinGW =
+          CGM.getContext().getTargetInfo().getTriple().getEnvironment() ==
+              llvm::Triple::GNU &&
+          CGM.getContext().getTargetInfo().getTriple().isOSWindows();
+      // MinGW always uses LinkOnceODRLinkage for type info.
+      if (RD->isDynamicClass() && !IsMinGW)
+        return CGM.getVTableLinkage(RD);
     }
 
     return llvm::GlobalValue::LinkOnceODRLinkage;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to