Author: rnk Date: Tue Nov 10 16:23:58 2015 New Revision: 252659 URL: http://llvm.org/viewvc/llvm-project?rev=252659&view=rev Log: [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. Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-structors-alias.cpp Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=252659&r1=252658&r2=252659&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Nov 10 16:23:58 2015 @@ -131,11 +131,6 @@ bool CodeGenModule::TryEmitDefinitionAsA 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::TryEmitDefinitionAsA 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 Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-structors-alias.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-structors-alias.cpp?rev=252659&r1=252658&r2=252659&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/microsoft-abi-structors-alias.cpp (original) +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-structors-alias.cpp Tue Nov 10 16:23:58 2015 @@ -24,3 +24,19 @@ void foo() { } // CHECK-DAG: @"\01??1B@test2@@UAE@XZ" = alias void (%"struct.test2::B"*), bitcast (void (%"struct.test2::A"*)* @"\01??1A@test2@@UAE@XZ" to void (%"struct.test2::B"*)*) } + +namespace test3 { +struct A { virtual ~A(); }; +A::~A() {} +} +// CHECK-DAG: define x86_thiscallcc void @"\01??1A@test3@@UAE@XZ"( +namespace test3 { +template <typename T> +struct B : A { + virtual ~B() { } +}; +template struct B<int>; +} +// This has to be weak, and emitting weak aliases is fragile, so we don't do the +// aliasing. +// CHECK-DAG: define weak_odr x86_thiscallcc void @"\01??1?$B@H@test3@@UAE@XZ"( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits