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