1// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 -std=c++11 | FileCheck %s
2
3// CHECK-DAG: @PR22043 = global i32 0, align 4
4typedef _Atomic(int) AtomicInt;
5AtomicInt PR22043 = AtomicInt();
6
7// CHECK-DAG: @_ZN7PR180978constant1aE = global { i16, i8 } { i16 1, i8 6 }, align 4
8// CHECK-DAG: @_ZN7PR180978constant1bE = global { i16, i8 } { i16 2, i8 6 }, align 4
9// CHECK-DAG: @_ZN7PR180978constant1cE = global { i16, i8 } { i16 3, i8 6 }, align 4
10// CHECK-DAG: @_ZN7PR180978constant1yE = global { { i16, i8 }, i32 } { { i16, i8 } { i16 4, i8 6 }, i32 5 }, align 4
11
12struct A {
13  _Atomic(int) i;
14  A(int j);
15  void v(int j);
16};
17// Storing to atomic values should be atomic
18// CHECK: store atomic i32
19void A::v(int j) { i = j; }
20// Initialising atomic values should not be atomic
21// CHECK-NOT: store atomic
22A::A(int j) : i(j) {}
23
24struct B {
25  int i;
26  B(int x) : i(x) {}
27};
28
29_Atomic(B) b;
30
31// CHECK-LABEL: define void @_Z11atomic_initR1Ai
32void atomic_init(A& a, int i) {
33  // CHECK-NOT: atomic
34  // CHECK: tail call void @_ZN1BC1Ei
35  __c11_atomic_init(&b, B(i));
36  // CHECK-NEXT: ret void
37}
38
39// CHECK-LABEL: define void @_Z16atomic_init_boolPU7_Atomicbb
40void atomic_init_bool(_Atomic(bool) *ab, bool b) {
41  // CHECK-NOT: atomic
42  // CHECK: {{zext i1.*to i8}}
43  // CHECK-NEXT: store i8
44  __c11_atomic_init(ab, b);
45  // CHECK-NEXT: ret void
46}
47
48struct AtomicBoolMember {
49  _Atomic(bool) ab;
50  AtomicBoolMember(bool b);
51};
52
53// CHECK-LABEL: define void @_ZN16AtomicBoolMemberC2Eb
54// CHECK: {{zext i1.*to i8}}
55// CHECK-NEXT: store i8
56// CHECK-NEXT: ret void
57AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { }
58
59namespace PR18097 {
60  namespace dynamic {
61    struct X {
62      X(int);
63      short n;
64      char c;
65    };
66
67    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
68    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1aE, i32 1)
69    _Atomic(X) a = X(1);
70
71    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
72    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1bE, i32 2)
73    _Atomic(X) b(X(2));
74
75    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
76    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1cE, i32 3)
77    _Atomic(X) c{X(3)};
78
79    struct Y {
80      _Atomic(X) a;
81      _Atomic(int) b;
82    };
83    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
84    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4)
85    // CHECK: store i32 5, i32* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 1)
86    Y y = { X(4), 5 };
87  }
88
89  // CHECKs at top of file.
90  namespace constant {
91    struct X {
92      constexpr X(int n) : n(n) {}
93      short n;
94      char c = 6;
95    };
96    _Atomic(X) a = X(1);
97    _Atomic(X) b(X(2));
98    _Atomic(X) c{X(3)};
99
100    struct Y {
101      _Atomic(X) a;
102      _Atomic(int) b;
103    };
104    Y y = { X(4), 5 };
105  }
106}
107