1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s
2 void t1() {
3   extern int& a;
4   int b = a;
5 }
6 
7 void t2(int& a) {
8   int b = a;
9 }
10 
11 int g;
12 int& gr = g;
13 int& grr = gr;
14 void t3() {
15   int b = gr;
16 }
17 
18 // Test reference binding.
19 
20 struct C { int a; };
21 void f(const bool&);
22 void f(const int&);
23 void f(const _Complex int&);
24 void f(const C&);
25 
26 C aggregate_return();
27 
28 bool& bool_reference_return();
29 int& int_reference_return();
30 _Complex int& complex_int_reference_return();
31 C& aggregate_reference_return();
32 
33 void 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 
45 void 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 
63 void 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 
75 void 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 
87 int& reference_return() {
88   return g;
89 }
90 
91 int reference_decl() {
92   int& a = g;
93   const int& b = 1;
94   return a+b;
95 }
96 
97 struct A {
98   int& b();
99 };
100 
101 void f(A* a) {
102   int b = a->b();
103 }
104 
105 // PR5122
106 void *foo = 0;
107 void * const & kFoo = foo;
108 
109 struct D : C { D(); ~D(); };
110 
111 void h() {
112   // CHECK: call void @_ZN1DD1Ev
113   const C& c = D();
114 }
115 
116 namespace 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.
140 namespace PR5227 {
141 void f(int &a) {
142   (a = 10) = 20;
143 }
144 }
145 
146 // PR5590
147 struct s0;
148 struct s1 { struct s0 &s0; };
149 void f0(s1 a) { s1 b = a; }
150 
151 // PR6024
152 // CHECK: @_Z2f2v()
153 // CHECK: alloca i32,
154 // CHECK-NEXT: store
155 // CHECK-NEXT: ret
156 const int &f2() { return 0; }
157 
158 // Don't constant fold const reference parameters with default arguments to
159 // their default arguments.
160 namespace 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.
172 namespace 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 
228 namespace N3 {
229 
230 // PR7326
231 
232 struct A {
233   explicit A(int);
234   ~A();
235 };
236 
237 // CHECK: define internal void @__cxx_global_var_init
238 // CHECK: call void @_ZN2N31AC1Ei(%"class.N2::X"* @_ZGRN2N35sA123E, i32 123)
239 // CHECK: call i32 @__cxa_atexit
240 // CHECK: ret void
241 const A &sA123 = A(123);
242 }
243 
244 namespace N4 {
245 
246 struct A {
247   A();
248   ~A();
249 };
250 
251 void f() {
252   // CHECK: define void @_ZN2N41fEv
253   // CHECK: call void @_ZN2N41AC1Ev(%"class.N2::X"* @_ZGRZN2N41fEvE2ar)
254   // CHECK: call i32 @__cxa_atexit
255   // CHECK: ret void
256   static const A& ar = A();
257 
258 }
259 }
260 
261 // PR9494
262 namespace N5 {
263 struct AnyS { bool b; };
264 void f(const bool&);
265 AnyS g();
266 void h() {
267   // CHECK: call i8 @_ZN2N51gEv()
268   // CHECK: call void @_ZN2N51fERKb(i8*
269   f(g().b);
270 }
271 }
272