diff options
| author | Reid Kleckner <reid@kleckner.net> | 2013-12-11 19:21:27 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2013-12-11 19:21:27 +0000 |
| commit | a12cd28bb3e23521ec623082c52c6c82e0a55bab (patch) | |
| tree | 29d8a009846b24e4692f09cded4c001d153cd2a2 /clang | |
| parent | 6d03fdb6a45daec2a661b217433a588e282f2b48 (diff) | |
| download | bcm5719-llvm-a12cd28bb3e23521ec623082c52c6c82e0a55bab.tar.gz bcm5719-llvm-a12cd28bb3e23521ec623082c52c6c82e0a55bab.zip | |
[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
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-structors.cpp | 15 |
2 files changed, 23 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 41f2c6c81fe..e3ab9df9a67 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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; diff --git a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp index c2f1395f47d..71cc31d9aec 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp @@ -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) |

