r252659 - [COFF] Don't try to emit weak aliases on COFF

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 10 14:23:58 PST 2015


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 at test2@@UAE at XZ" = alias void (%"struct.test2::B"*), bitcast (void (%"struct.test2::A"*)* @"\01??1A at test2@@UAE at XZ" to void (%"struct.test2::B"*)*)
 }
+
+namespace test3 {
+struct A { virtual ~A(); };
+A::~A() {}
+}
+// CHECK-DAG: define x86_thiscallcc void @"\01??1A at test3@@UAE at 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 at H@test3@@UAE at XZ"(




More information about the cfe-commits mailing list