Don't emit structors for available_externally globals (PR19933)
authorHans Wennborg <hans@hanshq.net>
Wed, 4 Jun 2014 21:04:54 +0000 (21:04 +0000)
committerHans Wennborg <hans@hanshq.net>
Wed, 4 Jun 2014 21:04:54 +0000 (21:04 +0000)
We would previously assert here when trying to figure out the section
for the global.

This makes us handle the situation more gracefully since the IR isn't
malformed.

Differential Revision: http://reviews.llvm.org/D4022

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210215 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/AsmPrinter.cpp
test/MC/COFF/global_ctors_dtors.ll

index 6c6d0dae9e74567f25434c40b4c056104d1c241c..49c2ee20c2060beb8156088cab486a65e8c6317d 100644 (file)
@@ -1349,9 +1349,14 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
     const TargetLoweringObjectFile &Obj = getObjFileLowering();
     const MCSymbol *KeySym = nullptr;
     const MCSection *KeySec = nullptr;
-    if (S.ComdatKey) {
-      KeySym = getSymbol(S.ComdatKey);
-      KeySec = getObjFileLowering().SectionForGlobal(S.ComdatKey, *Mang, TM);
+    if (GlobalValue *GV = S.ComdatKey) {
+      if (GV->hasAvailableExternallyLinkage())
+        // If the associated variable is available_externally, some other TU
+        // will provide its dynamic initializer.
+        continue;
+
+      KeySym = getSymbol(GV);
+      KeySec = getObjFileLowering().SectionForGlobal(GV, *Mang, TM);
     }
     const MCSection *OutputSection =
         (isCtor ? Obj.getStaticCtorSection(S.Priority, KeySym, KeySec)
index 046e93a6ce2305aaf73836032c46da9373c20b2f..735c493683f1f13c09cafc99b769d55b0d5f71a2 100644 (file)
 
 %ini = type { i32, void()*, i8* }
 
-@llvm.global_ctors = appending global [2 x %ini ] [
+@llvm.global_ctors = appending global [3 x %ini ] [
   %ini { i32 65535, void ()* @a_global_ctor, i8* null },
-  %ini { i32 65535, void ()* @b_global_ctor, i8* bitcast (i32* @b to i8*) }
+  %ini { i32 65535, void ()* @b_global_ctor, i8* bitcast (i32* @b to i8*) },
+  %ini { i32 65535, void ()* @c_global_ctor, i8* bitcast (i32* @c to i8*) }
 ]
 @llvm.global_dtors = appending global [1 x %ini ] [%ini { i32 65535, void ()* @a_global_dtor, i8* null }]
 
@@ -26,11 +27,18 @@ define void @a_global_ctor() nounwind {
 
 @b = global i32 zeroinitializer
 
+@c = available_externally dllimport global i32 zeroinitializer
+
 define void @b_global_ctor() nounwind {
   store i32 42, i32* @b
   ret void
 }
 
+define void @c_global_ctor() nounwind {
+  store i32 42, i32* @c
+  ret void
+}
+
 define void @a_global_dtor() nounwind {
   %1 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str2, i32 0, i32 0))
   ret void
@@ -45,11 +53,13 @@ define i32 @main() nounwind {
 ; WIN32: a_global_ctor
 ; WIN32: .section .CRT$XCU,"rd",associative .bss,{{_?}}b
 ; WIN32: b_global_ctor
+; WIN32-NOT: c_global_ctor
 ; WIN32: .section .CRT$XTX,"rd"
 ; WIN32: a_global_dtor
 ; MINGW32: .section .ctors,"wd"
 ; MINGW32: a_global_ctor
 ; MINGW32: .section .ctors,"wd",associative .bss,{{_?}}b
 ; MINGW32: b_global_ctor
+; MINGW32-NOT: c_global_ctor
 ; MINGW32: .section .dtors,"wd"
 ; MINGW32: a_global_dtor