]> granicus.if.org Git - clang/commitdiff
[MinGW] Emit typeinfo locally for dllimported classes without key functions
authorMartin Storsjo <martin@martin.st>
Fri, 2 Feb 2018 06:22:35 +0000 (06:22 +0000)
committerMartin Storsjo <martin@martin.st>
Fri, 2 Feb 2018 06:22:35 +0000 (06:22 +0000)
This fixes building Qt as shared libraries with clang in MinGW
mode; previously subclasses of the QObjectData class (in other
DLLs than the base DLL) failed to find the typeinfo symbols
(that neither were emitted in the base DLL nor in the DLL
containing the subclass).

If the virtual destructor in the newly added testcase wouldn't
be pure (or if there'd be another non-pure virtual method),
it'd be a key function and things would work out even before this
change. Make sure to locally emit the typeinfo for these classes
as well.

This matches what GCC does in this specific testcase.

This fixes the root issue that spawned PR35146. (The difference
to GCC that is initially described in that bug still is present
though.)

Differential Revision: https://reviews.llvm.org/D42641

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

lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/dllimport-missing-key.cpp [new file with mode: 0644]
test/CodeGenCXX/dllimport-rtti.cpp

index 861f29a298b68ca7e08defb641e8ca363d5b4750..8fd0839487d4cd102fb6310e1ccc95f21584a4cb 100644 (file)
@@ -2761,6 +2761,11 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
     // N.B. We must always emit the RTTI data ourselves if there exists a key
     // function.
     bool IsDLLImport = RD->hasAttr<DLLImportAttr>();
+
+    // Don't import the RTTI but emit it locally.
+    if (CGM.getTriple().isWindowsGNUEnvironment() && IsDLLImport)
+      return false;
+
     if (CGM.getVTables().isVTableExternal(RD))
       return IsDLLImport && !CGM.getTriple().isWindowsItaniumEnvironment()
                  ? false
diff --git a/test/CodeGenCXX/dllimport-missing-key.cpp b/test/CodeGenCXX/dllimport-missing-key.cpp
new file mode 100644 (file)
index 0000000..d8ef7aa
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s
+
+class __declspec(dllimport) QObjectData {
+public:
+    virtual ~QObjectData() = 0;
+    void *ptr;
+
+    int method() const;
+};
+
+class LocalClass : public QObjectData {
+};
+
+void call() {
+    (new LocalClass())->method();
+}
+
+// GNU-DAG: @_ZTV11QObjectData = available_externally dllimport
+// GNU-DAG: @_ZTS11QObjectData = linkonce_odr
+// GNU-DAG: @_ZTI11QObjectData = linkonce_odr
index 91e747ae1c15ffa290400b97d9963711f844eb99..dfb39a15eda568fa6891db77d5084624fa5d73d7 100644 (file)
@@ -12,7 +12,7 @@ struct __declspec(dllimport) S {
 // MSVC-DAG: @"\01??_R3S@@8" = linkonce_odr
 
 // GNU-DAG: @_ZTV1S = available_externally dllimport
-// GNU-DAG: @_ZTI1S = external dllimport
+// GNU-DAG: @_ZTI1S = linkonce_odr
 
 struct U : S {
 } u;