1// RUN: not %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
2void t1() {
3  // CHECK-LABEL: define void @_Z2t1v
4  // CHECK: [[REFLOAD:%.*]] = load i32*, i32** @a, align 8
5  // CHECK: load i32, i32* [[REFLOAD]], align 4
6  extern int& a;
7  int b = a;
8}
9
10void t2(int& a) {
11  // CHECK-LABEL: define void @_Z2t2Ri
12  // CHECK: [[REFLOAD2:%.*]] = load i32*, i32** {{.*}}, align 8
13  // CHECK: load i32, i32* [[REFLOAD2]], align 4
14  int b = a;
15}
16
17int g;
18int& gr = g;
19int& grr = gr;
20void t3() {
21  int b = gr;
22}
23
24// Test reference binding.
25
26struct C { int a; };
27void f(const bool&);
28void f(const int&);
29void f(const _Complex int&);
30void f(const C&);
31
32C aggregate_return();
33
34bool& bool_reference_return();
35int& int_reference_return();
36_Complex int& complex_int_reference_return();
37C& aggregate_reference_return();
38
39void test_bool() {
40  bool a = true;
41  f(a);
42
43  f(true);
44
45  bool_reference_return() = true;
46  a = bool_reference_return();
47
48  struct { const bool& b; } b = { true };
49}
50
51void test_scalar() {
52  int a = 10;
53  f(a);
54
55  struct { int bitfield : 3; } s = { 3 };
56  f(s.bitfield);
57
58  f(10);
59
60  __attribute((vector_size(16))) typedef int vec4;
61  f((vec4){1,2,3,4}[0]);
62
63  int_reference_return() = 10;
64  a = int_reference_return();
65
66  struct { const int& a; } agg = { 10 };
67}
68
69void test_complex() {
70  _Complex int a = 10i;
71  f(a);
72
73  f(10i);
74
75  complex_int_reference_return() = 10i;
76  a = complex_int_reference_return();
77
78  struct { const _Complex int &a; } agg = { 10i };
79}
80
81void test_aggregate() {
82  C c;
83  f(c);
84
85  f(aggregate_return());
86  aggregate_reference_return().a = 10;
87
88  c = aggregate_reference_return();
89
90  struct { const C& a; } agg = { C() };
91}
92
93int& reference_return() {
94  return g;
95}
96
97int reference_decl() {
98  int& a = g;
99  const int& b = 1;
100  return a+b;
101}
102
103struct A {
104  int& b();
105};
106
107void f(A* a) {
108  int b = a->b();
109}
110
111// PR5122
112void *foo = 0;
113void * const & kFoo = foo;
114
115struct D : C { D(); ~D(); };
116
117void h() {
118  // CHECK: call void @_ZN1DD1Ev
119  const C& c = D();
120}
121
122namespace T {
123  struct A {
124    A();
125    ~A();
126  };
127
128  struct B {
129    B();
130    ~B();
131    A f();
132  };
133
134  void f() {
135    // CHECK: call void @_ZN1T1BC1Ev
136    // CHECK: call void @_ZN1T1B1fEv
137    // CHECK: call void @_ZN1T1BD1Ev
138    const A& a = B().f();
139    // CHECK: call void @_ZN1T1fEv
140    f();
141    // CHECK: call void @_ZN1T1AD1Ev
142  }
143}
144
145// PR5227.
146namespace PR5227 {
147void f(int &a) {
148  (a = 10) = 20;
149}
150}
151
152// PR5590
153struct s0;
154struct s1 { struct s0 &s0; };
155void f0(s1 a) { s1 b = a; }
156
157// PR6024
158// CHECK: @_Z2f2v()
159// CHECK: alloca i32,
160// CHECK-NEXT: store
161// CHECK-NEXT: ret
162const int &f2() { return 0; }
163
164// Don't constant fold const reference parameters with default arguments to
165// their default arguments.
166namespace N1 {
167  const int foo = 1;
168  // CHECK: @_ZN2N14test
169  void test(const int& arg = foo) {
170    // Ensure this array is on the stack where we can set values instead of
171    // being a global constant.
172    // CHECK: %args_array = alloca
173    const int* const args_array[] = { &arg };
174  }
175}
176
177// Bind to subobjects while extending the life of the complete object.
178namespace N2 {
179  class X {
180  public:
181    X(const X&);
182    X &operator=(const X&);
183    ~X();
184  };
185
186  struct P {
187    X first;
188  };
189
190  P getP();
191
192  // CHECK-LABEL: define void @_ZN2N21fEi
193  // CHECK: call void @_ZN2N24getPEv
194  // CHECK: getelementptr inbounds
195  // CHECK: store i32 17
196  // CHECK: call void @_ZN2N21PD1Ev
197  void f(int i) {
198    const X& xr = getP().first;
199    i = 17;
200  }
201
202  struct SpaceWaster {
203    int i, j;
204  };
205
206  struct ReallyHasX {
207    X x;
208  };
209
210  struct HasX : ReallyHasX { };
211
212  struct HasXContainer {
213    HasX has;
214  };
215
216  struct Y : SpaceWaster, HasXContainer { };
217  struct Z : SpaceWaster, Y { };
218
219  Z getZ();
220
221  // CHECK-LABEL: define void @_ZN2N21gEi
222  // CHECK: call void @_ZN2N24getZEv
223  // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
224  // CHECK: {{getelementptr inbounds.*i32 0, i32 0}}
225  // CHECK: store i32 19
226  // CHECK: call void @_ZN2N21ZD1Ev
227  // CHECK: ret void
228  void g(int i) {
229    const X &xr = getZ().has.x;
230    i = 19;
231  }
232}
233
234namespace N3 {
235
236// PR7326
237
238struct A {
239  explicit A(int);
240  ~A();
241};
242
243// CHECK-LABEL: define internal void @__cxx_global_var_init
244// CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E_, i32 123)
245// CHECK: call i32 @__cxa_atexit
246// CHECK: ret void
247const A &sA123 = A(123);
248}
249
250namespace N4 {
251
252struct A {
253  A();
254  ~A();
255};
256
257void f() {
258  // CHECK-LABEL: define void @_ZN2N41fEv
259  // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar_)
260  // CHECK: call i32 @__cxa_atexit
261  // CHECK: ret void
262  static const A& ar = A();
263
264}
265}
266
267// PR9494
268namespace N5 {
269struct AnyS { bool b; };
270void f(const bool&);
271AnyS g();
272void h() {
273  // CHECK: call i8 @_ZN2N51gEv()
274  // CHECK: call void @_ZN2N51fERKb(i8*
275  f(g().b);
276}
277}
278
279// PR9565
280namespace PR9565 {
281  struct a { int a : 10, b : 10; };
282  // CHECK-LABEL: define void @_ZN6PR95651fEv()
283  void f() {
284    // CHECK: call void @llvm.memcpy
285    a x = { 0, 0 };
286    // CHECK: [[WITH_SEVENTEEN:%[.a-zA-Z0-9]+]] = or i32 [[WITHOUT_SEVENTEEN:%[.a-zA-Z0-9]+]], 17
287    // CHECK: store i32 [[WITH_SEVENTEEN]], i32* [[XA:%[.a-zA-Z0-9]+]]
288    x.a = 17;
289    // CHECK-NEXT: bitcast
290    // CHECK-NEXT: load
291    // CHECK-NEXT: shl
292    // CHECK-NEXT: ashr
293    // CHECK-NEXT: store i32
294    // CHECK-NEXT: store i32*
295    const int &y = x.a;
296    // CHECK-NEXT: bitcast
297    // CHECK-NEXT: load
298    // CHECK-NEXT: and
299    // CHECK-NEXT: or i32 {{.*}}, 19456
300    // CHECK-NEXT: store i32
301    x.b = 19;
302    // CHECK-NEXT: ret void
303  }
304}
305
306namespace N6 {
307  extern struct x {char& x;}y;
308  int a() { return y.x; }
309  // CHECK-LABEL: define i32 @_ZN2N61aEv
310  // CHECK: [[REFLOAD3:%.*]] = load i8*, i8** getelementptr inbounds (%"struct.N6::x", %"struct.N6::x"* @_ZN2N61yE, i32 0, i32 0), align 8
311  // CHECK: load i8, i8* [[REFLOAD3]], align 1
312}
313