Use atexit when __cxa_atexit isn't available instead of adding a
global destructor entry. For some reason this isn't enabled for
apple-kexts; it'd be good to have documentation for that.
Based on a patch by Nakamura Takumi!
llvm-svn: 154191
diff --git a/clang/test/CodeGenCXX/arm.cpp b/clang/test/CodeGenCXX/arm.cpp
index 36c6c1c..6c60f30 100644
--- a/clang/test/CodeGenCXX/arm.cpp
+++ b/clang/test/CodeGenCXX/arm.cpp
@@ -20,9 +20,17 @@
// The global dtor needs the right calling conv with -fno-use-cxa-atexit
// rdar://7817590
-// Checked at end of file.
bar baz;
+// PR9593
+// Make sure atexit(3) is used for global dtors.
+
+// CHECK: call [[BAR:%.*]]* @_ZN3barC1Ev(
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_baz)
+
+// CHECK: define internal void @__dtor_baz()
+// CHECK: call [[BAR]]* @_ZN3barD1Ev([[BAR]]* @baz)
+
// Destructors and constructors must return this.
namespace test1 {
void foo();
@@ -357,5 +365,5 @@
// CHECK: call void @_ZN5test21CD0Ev(
// CHECK: ret void
-// CHECK: @_GLOBAL__D_a()
-// CHECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)
+// CH_ECK: @_GLOBAL__D_a()
+// CH_ECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)
diff --git a/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp b/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp
index 1e125e3..def97b2 100644
--- a/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp
+++ b/clang/test/CodeGenCXX/global-dtor-no-atexit.cpp
@@ -3,10 +3,15 @@
// PR7097
// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -mconstructor-aliases -emit-llvm -o - | FileCheck %s
-// CHECK: define internal void @_GLOBAL__D_a()
-// CHECK: call void @_ZN1AD1Ev(%class.A* @b)
-// CHECK: call void @_ZN1AD1Ev(%class.A* @a)
-// CHECK: }
+// CHECK: call void @_ZN1AC1Ev([[A:%.*]]* @a)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_a)
+// CHECK: define internal void @__dtor_a() nounwind
+// CHECK: call void @_ZN1AD1Ev([[A]]* @a)
+
+// CHECK: call void @_ZN1AC1Ev([[A]]* @b)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor_b)
+// CHECK: define internal void @__dtor_b() nounwind
+// CHECK: call void @_ZN1AD1Ev([[A]]* @b)
class A {
public:
@@ -15,3 +20,25 @@
};
A a, b;
+
+// PR9593
+// CHECK: define void @_Z4funcv()
+// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ4funcvE2a1)
+// CHECK: call void @_ZN1AC1Ev([[A]]* @_ZZ4funcvE2a1)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor__ZZ4funcvE2a1)
+// CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ4funcvE2a1)
+
+// CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZ4funcvE2a2)
+// CHECK: call void @_ZN1AC1Ev([[A]]* @_ZZ4funcvE2a2)
+// CHECK-NEXT: call i32 @atexit(void ()* @__dtor__ZZ4funcvE2a2)
+// CHECK-NEXT: call void @__cxa_guard_release(i64* @_ZGVZ4funcvE2a2)
+
+// CHECK: define internal void @__dtor__ZZ4funcvE2a1() nounwind
+// CHECK: call void @_ZN1AD1Ev([[A]]* @_ZZ4funcvE2a1)
+
+// CHECK: define internal void @__dtor__ZZ4funcvE2a2() nounwind
+// CHECK: call void @_ZN1AD1Ev([[A]]* @_ZZ4funcvE2a2)
+
+void func() {
+ static A a1, a2;
+}
diff --git a/clang/test/CodeGenCXX/global-init.cpp b/clang/test/CodeGenCXX/global-init.cpp
index 053210b..8e6ef77 100644
--- a/clang/test/CodeGenCXX/global-init.cpp
+++ b/clang/test/CodeGenCXX/global-init.cpp
@@ -12,7 +12,7 @@
struct D { ~D(); };
-// CHECK: @__dso_handle = external unnamed_addr global i8*
+// CHECK: @__dso_handle = external unnamed_addr global i8
// CHECK: @c = global %struct.C zeroinitializer, align 8
// It's okay if we ever implement the IR-generation optimization to remove this.
@@ -24,18 +24,18 @@
// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), align 8
// CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
-// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* @__dso_handle)
A a;
// CHECK: call void @_ZN1BC1Ev(%struct.B* @b)
-// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B* @b, i32 0, i32 0), i8* @__dso_handle)
B b;
// PR6205: this should not require a global initializer
// CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c)
C c;
-// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D* @d, i32 0, i32 0), i8* @__dso_handle)
D d;
// <rdar://problem/7458115>
diff --git a/clang/test/CodeGenCXX/static-init.cpp b/clang/test/CodeGenCXX/static-init.cpp
index 7e840f5..ed659de 100644
--- a/clang/test/CodeGenCXX/static-init.cpp
+++ b/clang/test/CodeGenCXX/static-init.cpp
@@ -17,7 +17,7 @@
// CHECK: load atomic i8* bitcast (i64* @_ZGVZ1fvE1a to i8*) acquire, align 1
// CHECK: call i32 @__cxa_guard_acquire
// CHECK: call void @_ZN1AC1Ev
- // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+ // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* @__dso_handle)
// CHECK: call void @__cxa_guard_release
static A a;
}