xref: /aosp_15_r20/external/clang/test/CodeGenCXX/static-data-member.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | \
3*67e74705SXin Li // RUN: FileCheck --check-prefix=MACHO %s
4*67e74705SXin Li 
5*67e74705SXin Li // CHECK: @_ZN5test11A1aE = constant i32 10, align 4
6*67e74705SXin Li // CHECK: @_ZN5test212_GLOBAL__N_11AIiE1xE = internal global i32 0, align 4
7*67e74705SXin Li // CHECK: @_ZN5test31AIiE1xE = weak_odr global i32 0, comdat, align 4
8*67e74705SXin Li // CHECK: @_ZGVN5test31AIiE1xE = weak_odr global i64 0, comdat($_ZN5test31AIiE1xE)
9*67e74705SXin Li // MACHO: @_ZGVN5test31AIiE1xE = weak_odr global i64 0
10*67e74705SXin Li // MACHO-NOT: comdat
11*67e74705SXin Li 
12*67e74705SXin Li // CHECK: _ZN5test51U2k0E = global i32 0
13*67e74705SXin Li // CHECK: _ZN5test51U2k1E = global i32 0
14*67e74705SXin Li // CHECK: _ZN5test51U2k2E = constant i32 76
15*67e74705SXin Li // CHECK-NOT: test51U2k3E
16*67e74705SXin Li // CHECK-NOT: test51U2k4E
17*67e74705SXin Li 
18*67e74705SXin Li // PR5564.
19*67e74705SXin Li namespace test1 {
20*67e74705SXin Li   struct A {
21*67e74705SXin Li     static const int a = 10;
22*67e74705SXin Li   };
23*67e74705SXin Li 
24*67e74705SXin Li   const int A::a;
25*67e74705SXin Li 
26*67e74705SXin Li   struct S {
27*67e74705SXin Li     static int i;
28*67e74705SXin Li   };
29*67e74705SXin Li 
f()30*67e74705SXin Li   void f() {
31*67e74705SXin Li     int a = S::i;
32*67e74705SXin Li   }
33*67e74705SXin Li }
34*67e74705SXin Li 
35*67e74705SXin Li // Test that we don't use guards for initializing template static data
36*67e74705SXin Li // members with internal linkage.
37*67e74705SXin Li namespace test2 {
38*67e74705SXin Li   int foo();
39*67e74705SXin Li 
40*67e74705SXin Li   namespace {
41*67e74705SXin Li     template <class T> struct A {
42*67e74705SXin Li       static int x;
43*67e74705SXin Li     };
44*67e74705SXin Li 
45*67e74705SXin Li     template <class T> int A<T>::x = foo();
46*67e74705SXin Li     template struct A<int>;
47*67e74705SXin Li   }
48*67e74705SXin Li 
49*67e74705SXin Li   // CHECK-LABEL: define internal void @__cxx_global_var_init()
50*67e74705SXin Li   // CHECK:      [[TMP:%.*]] = call i32 @_ZN5test23fooEv()
51*67e74705SXin Li   // CHECK-NEXT: store i32 [[TMP]], i32* @_ZN5test212_GLOBAL__N_11AIiE1xE, align 4
52*67e74705SXin Li   // CHECK-NEXT: ret void
53*67e74705SXin Li }
54*67e74705SXin Li 
55*67e74705SXin Li // Test that we don't use threadsafe statics when initializing
56*67e74705SXin Li // template static data members.
57*67e74705SXin Li namespace test3 {
58*67e74705SXin Li   int foo();
59*67e74705SXin Li 
60*67e74705SXin Li   template <class T> struct A {
61*67e74705SXin Li     static int x;
62*67e74705SXin Li   };
63*67e74705SXin Li 
64*67e74705SXin Li   template <class T> int A<T>::x = foo();
65*67e74705SXin Li   template struct A<int>;
66*67e74705SXin Li 
67*67e74705SXin Li   // CHECK-LABEL: define internal void @__cxx_global_var_init.1() {{.*}} comdat($_ZN5test31AIiE1xE)
68*67e74705SXin Li   // MACHO-LABEL: define internal void @__cxx_global_var_init.1()
69*67e74705SXin Li   // MACHO-NOT: comdat
70*67e74705SXin Li   // CHECK:      [[GUARDBYTE:%.*]] = load i8, i8* bitcast (i64* @_ZGVN5test31AIiE1xE to i8*)
71*67e74705SXin Li   // CHECK-NEXT: [[UNINITIALIZED:%.*]] = icmp eq i8 [[GUARDBYTE]], 0
72*67e74705SXin Li   // CHECK-NEXT: br i1 [[UNINITIALIZED]]
73*67e74705SXin Li   // CHECK:      [[TMP:%.*]] = call i32 @_ZN5test33fooEv()
74*67e74705SXin Li   // CHECK-NEXT: store i32 [[TMP]], i32* @_ZN5test31AIiE1xE, align 4
75*67e74705SXin Li   // CHECK-NEXT: store i64 1, i64* @_ZGVN5test31AIiE1xE
76*67e74705SXin Li   // CHECK-NEXT: br label
77*67e74705SXin Li   // CHECK:      ret void
78*67e74705SXin Li }
79*67e74705SXin Li 
80*67e74705SXin Li // Test that we can fold member lookup expressions which resolve to static data
81*67e74705SXin Li // members.
82*67e74705SXin Li namespace test4 {
83*67e74705SXin Li   struct A {
84*67e74705SXin Li     static const int n = 76;
85*67e74705SXin Li   };
86*67e74705SXin Li 
f(A * a)87*67e74705SXin Li   int f(A *a) {
88*67e74705SXin Li     // CHECK-LABEL: define i32 @_ZN5test41fEPNS_1AE
89*67e74705SXin Li     // CHECK: ret i32 76
90*67e74705SXin Li     return a->n;
91*67e74705SXin Li   }
92*67e74705SXin Li }
93*67e74705SXin Li 
94*67e74705SXin Li // Test that static data members in unions behave properly.
95*67e74705SXin Li namespace test5 {
96*67e74705SXin Li   union U {
97*67e74705SXin Li     static int k0;
98*67e74705SXin Li     static const int k1;
99*67e74705SXin Li     static const int k2 = 76;
100*67e74705SXin Li     static const int k3;
101*67e74705SXin Li     static const int k4 = 81;
102*67e74705SXin Li   };
103*67e74705SXin Li   int U::k0;
104*67e74705SXin Li   const int U::k1 = (k0 = 9, 42);
105*67e74705SXin Li   const int U::k2;
106*67e74705SXin Li 
107*67e74705SXin Li   // CHECK: store i32 9, i32* @_ZN5test51U2k0E
108*67e74705SXin Li   // CHECK: store i32 {{.*}}, i32* @_ZN5test51U2k1E
109*67e74705SXin Li   // CHECK-NOT: store {{.*}} i32* @_ZN5test51U2k2E
110*67e74705SXin Li }
111