Skip to content

Commit

Permalink
Don't emit strong vtable definitions for imported classes with key fu…
Browse files Browse the repository at this point in the history
…nctions (PR21355)

Clang would previously assert on the following code when targeting MinGW:

  struct __declspec(dllimport) S {
      virtual ~S();
  };
  S::~S() {}

Because ~S is a key function and the class is dllimport, we would try to emit a
strong definition of the vtable, with dllimport - which is a conflict. We
should not emit strong vtable definitions for imported classes.

Differential Revision: http://reviews.llvm.org/D5944

llvm-svn: 220532
  • Loading branch information
zmodem committed Oct 23, 2014
1 parent e05afd4 commit ec53c29
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGVTables.cpp
Expand Up @@ -677,7 +677,8 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {

// We're at the end of the translation unit, so the current key
// function is fully correct.
if (const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD)) {
const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD);
if (keyFunction && !RD->hasAttr<DLLImportAttr>()) {
// If this class has a key function, use that to determine the
// linkage of the vtable.
const FunctionDecl *def = nullptr;
Expand Down
12 changes: 12 additions & 0 deletions clang/test/CodeGenCXX/dllimport.cpp
Expand Up @@ -672,6 +672,18 @@ namespace PR19933 {
// MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
}

namespace PR21355 {
struct __declspec(dllimport) S {
virtual ~S();
};
S::~S() {}

// S::~S is a key function, so we would ordinarily emit a strong definition for
// the vtable. However, S is imported, so the vtable should be too.

// GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*]
}

// MS ignores DLL attributes on partial specializations.
template <typename T> struct PartiallySpecializedClassTemplate {};
template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
Expand Down

0 comments on commit ec53c29

Please sign in to comment.