summaryrefslogtreecommitdiff
path: root/clang/test/CodeGenCXX/static-init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX/static-init.cpp')
-rw-r--r--clang/test/CodeGenCXX/static-init.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/static-init.cpp b/clang/test/CodeGenCXX/static-init.cpp
new file mode 100644
index 0000000..74278f7
--- /dev/null
+++ b/clang/test/CodeGenCXX/static-init.cpp
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
+// CHECK: @base_req = global [4 x i8] c"foo\00", align 1
+// CHECK: @base_req_uchar = global [4 x i8] c"bar\00", align 1
+
+// CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
+// CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
+
+struct A {
+ A();
+ ~A();
+};
+
+void f() {
+ // 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* @__dso_handle)
+ // CHECK: call void @__cxa_guard_release
+ static A a;
+}
+
+void g() {
+ // CHECK: call noalias i8* @_Znwm(i64 1)
+ // CHECK: call void @_ZN1AC1Ev(
+ static A& a = *new A;
+}
+
+int a();
+void h() {
+ static const int i = a();
+}
+
+inline void h2() {
+ static int i = a();
+}
+
+void h3() {
+ h2();
+}
+
+// PR6980: this shouldn't crash
+namespace test0 {
+ struct A { A(); };
+ __attribute__((noreturn)) int throw_exception();
+
+ void test() {
+ throw_exception();
+ static A r;
+ }
+}
+
+namespace test1 {
+ // CHECK: define internal i32 @_ZN5test1L6getvarEi(
+ static inline int getvar(int index) {
+ static const int var[] = { 1, 0, 2, 4 };
+ return var[index];
+ }
+
+ void test() { (void) getvar(2); }
+}
+
+// Make sure we emit the initializer correctly for the following:
+char base_req[] = { "foo" };
+unsigned char base_req_uchar[] = { "bar" };
+
+namespace union_static_local {
+ // CHECK: define internal void @_ZZN18union_static_local4testEvEN1c4mainEv
+ // CHECK: call void @_ZN18union_static_local1fEPNS_1xE(%"union.union_static_local::x"* bitcast ({ [2 x i8*] }* @_ZZN18union_static_local4testEvE3foo to %"union.union_static_local::x"*))
+ union x { long double y; const char *x[2]; };
+ void f(union x*);
+ void test() {
+ static union x foo = { .x = { "a", "b" } };
+ struct c {
+ static void main() {
+ f(&foo);
+ }
+ };
+ c::main();
+ }
+}
+
+// rdar://problem/11091093
+// Static variables should be consistent across constructor
+// or destructor variants.
+namespace test2 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ struct B : virtual A {
+ B();
+ ~B();
+ };
+
+ // If we ever implement this as a delegate ctor call, just change
+ // this to take variadic arguments or something.
+ extern int foo();
+ B::B() {
+ static int x = foo();
+ }
+ // CHECK: define void @_ZN5test21BC1Ev
+ // CHECK: load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+ // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK: store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+ // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+ // CHECK: define void @_ZN5test21BC2Ev
+ // CHECK: load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+ // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK: store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+ // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+ // This is just for completeness, because we actually emit this
+ // using a delegate dtor call.
+ B::~B() {
+ static int y = foo();
+ }
+ // CHECK: define void @_ZN5test21BD1Ev(
+ // CHECK: call void @_ZN5test21BD2Ev(
+
+ // CHECK: define void @_ZN5test21BD2Ev(
+ // CHECK: load atomic i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire,
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y)
+ // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+ // CHECK: store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y,
+ // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BD1EvE1y)
+}
+
+// This shouldn't error out.
+namespace test3 {
+ struct A {
+ A();
+ ~A();
+ };
+
+ struct B : virtual A {
+ B();
+ ~B();
+ };
+
+ B::B() {
+ union U { char x; int i; };
+ static U u = { 'a' };
+ }
+ // CHECK: define void @_ZN5test31BC1Ev(
+ // CHECK: define void @_ZN5test31BC2Ev(
+}