diff options
author | Reid Kleckner <rnk@google.com> | 2015-11-10 22:23:58 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-11-10 22:23:58 +0000 |
commit | 489cfe1401cd12ada30e7f73e4769b0eca30651a (patch) | |
tree | d2626d5930ced7be7468aa505064720dad71ab8c /clang/lib/CodeGen/CGCXX.cpp | |
parent | b7e286bed7d7e7c044a54785f30ca26894fda6b2 (diff) | |
download | bcm5719-llvm-489cfe1401cd12ada30e7f73e4769b0eca30651a.tar.gz bcm5719-llvm-489cfe1401cd12ada30e7f73e4769b0eca30651a.zip |
[COFF] Don't try to emit weak aliases on COFF
This comes up when a derived class destructor is equivalent to a base
class destructor defined in the same TU, and we try to alias them.
A COFF weak alias cannot satisfy a normal undefined symbol reference
from another TU. The other TU must also mark the referenced symbol as
weak, and we can't rely on that.
Clang already has a special case here for dllexport, but we failed to
realize that the problem also applies to other non-discardable symbols
such as those from explicit template instantiations.
Fixes PR25477.
llvm-svn: 252659
Diffstat (limited to 'clang/lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index ea32e382705..6847df9b749 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -131,11 +131,6 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, if (!llvm::GlobalAlias::isValidLinkage(Linkage)) return true; - // Don't create a weak alias for a dllexport'd symbol. - if (AliasDecl.getDecl()->hasAttr<DLLExportAttr>() && - llvm::GlobalValue::isWeakForLinker(Linkage)) - return true; - llvm::GlobalValue::LinkageTypes TargetLinkage = getFunctionLinkage(TargetDecl); @@ -173,6 +168,16 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, return false; } + // If we have a weak, non-discardable alias (weak, weak_odr), like an extern + // template instantiation or a dllexported class, avoid forming it on COFF. + // A COFF weak external alias cannot satisfy a normal undefined symbol + // reference from another TU. The other TU must also mark the referenced + // symbol as weak, which we cannot rely on. + if (llvm::GlobalValue::isWeakForLinker(Linkage) && + getTriple().isOSBinFormatCOFF()) { + return true; + } + if (!InEveryTU) { // If we don't have a definition for the destructor yet, don't // emit. We can't emit aliases to declarations; that's just not |