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