[ms-cxxabi] Fix linkage of dtor thunks for anonymous classes

We were mistakengly giving linkonce_odr linkage instead of internal
linkage to the deleting and complete destructor thunks for classes in
anonymous namespaces.

Fixes PR17273.

llvm-svn: 197060
This commit is contained in:
Reid Kleckner 2013-12-11 19:21:27 +00:00
parent 6d03fdb6a4
commit a12cd28bb3
2 changed files with 23 additions and 6 deletions

View File

@ -585,11 +585,6 @@ llvm::GlobalValue::LinkageTypes
CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
if (isa<CXXDestructorDecl>(D) &&
getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
GD.getDtorType()))
return llvm::Function::LinkOnceODRLinkage;
GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
if (Linkage == GVA_Internal)
@ -630,7 +625,14 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
return !Context.getLangOpts().AppleKext
? llvm::Function::WeakODRLinkage
: llvm::Function::ExternalLinkage;
// Destructor variants in the Microsoft C++ ABI are always linkonce_odr thunks
// emitted on an as-needed basis.
if (isa<CXXDestructorDecl>(D) &&
getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
GD.getDtorType()))
return llvm::Function::LinkOnceODRLinkage;
// Otherwise, we have strong external linkage.
assert(Linkage == GVA_StrongExternal);
return llvm::Function::ExternalLinkage;

View File

@ -299,3 +299,18 @@ void call_nv_deleting_dtor(D *d) {
}
}
// Dtor thunks for classes in anonymous namespaces should be internal, not
// linkonce_odr.
namespace {
struct A {
virtual ~A() { }
};
}
void *getA() {
return (void*)new A();
}
// CHECK: define internal x86_thiscallcc void @"\01??_GA@?A@@UAEPAXI@Z"
// CHECK: (%"struct.<anonymous namespace>::A"* %this, i32 %should_call_delete)
// CHECK: define internal x86_thiscallcc void @"\01??1A@?A@@UAE@XZ"
// CHECK: (%"struct.<anonymous namespace>::A"* %this)