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