aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp6
-rw-r--r--test/CodeGenCXX/cxx11-thread-local.cpp56
2 files changed, 62 insertions, 0 deletions
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index fc908804c0..d683493a83 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -51,6 +51,12 @@ struct wantslist1 {
// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZL25globalInitList1__initlist, i32 0, i32 0), i{{32|64}} 3 }
std::initializer_list<int> globalInitList1 = {1, 2, 3};
+namespace thread_local_global_array {
+ // CHECK: @_ZN25thread_local_global_arrayL11x__initlistE = internal thread_local global [4 x i32] [i32 1, i32 2, i32 3, i32 4]
+ // CHECK: @_ZN25thread_local_global_array1xE = thread_local global {{.*}} @_ZN25thread_local_global_arrayL11x__initlistE, {{.*}} i64 4
+ std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
+}
+
// CHECK: @_ZL25globalInitList2__initlist = internal global [2 x %{{[^ ]*}}] zeroinitializer
// CHECK: @globalInitList2 = global %{{[^ ]+}} { %[[WITHARG:[^ *]+]]* getelementptr inbounds ([2 x
// CHECK: appending global
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
new file mode 100644
index 0000000000..5ed582d232
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+
+int g();
+
+// CHECK: @_ZZ1fvE1n = internal thread_local global i32 0
+// CHECK: @_ZGVZ1fvE1n = internal thread_local global i8 0
+
+// CHECK: @_ZZ8tls_dtorvE1s = internal thread_local global
+// CHECK: @_ZGVZ8tls_dtorvE1s = internal thread_local global i8 0
+
+// CHECK: @_ZZ8tls_dtorvE1t = internal thread_local global
+// CHECK: @_ZGVZ8tls_dtorvE1t = internal thread_local global i8 0
+
+// CHECK: @_ZZ8tls_dtorvE1u = internal thread_local global
+// CHECK: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0
+// CHECK: @_ZGRZ8tls_dtorvE1u = internal thread_local global
+
+// CHECK: define i32 @_Z1fv()
+int f() {
+ // CHECK: %[[GUARD:.*]] = load i8* @_ZGVZ1fvE1n, align 1
+ // CHECK: %[[NEED_INIT:.*]] = icmp eq i8 %[[GUARD]], 0
+ // CHECK: br i1 %[[NEED_INIT]]
+
+ // CHECK: %[[CALL:.*]] = call i32 @_Z1gv()
+ // CHECK: store i32 %[[CALL]], i32* @_ZZ1fvE1n, align 4
+ // CHECK: store i8 1, i8* @_ZGVZ1fvE1n
+ // CHECK: br label
+ static thread_local int n = g();
+
+ // CHECK: load i32* @_ZZ1fvE1n, align 4
+ return n;
+}
+
+struct S { S(); ~S(); };
+struct T { ~T(); };
+
+// CHECK: define void @_Z8tls_dtorv()
+void tls_dtor() {
+ // CHECK: load i8* @_ZGVZ8tls_dtorvE1s
+ // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZZ8tls_dtorvE1s)
+ // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZZ8tls_dtorvE1s{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1s
+ static thread_local S s;
+
+ // CHECK: load i8* @_ZGVZ8tls_dtorvE1t
+ // CHECK-NOT: _ZN1T
+ // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1TD1Ev {{.*}}@_ZZ8tls_dtorvE1t{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1t
+ static thread_local T t;
+
+ // CHECK: load i8* @_ZGVZ8tls_dtorvE1u
+ // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u)
+ // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u{{.*}} @__dso_handle
+ // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1u
+ static thread_local const S &u = S();
+}