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