1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
2*f4a2713aSLionel Sambuc void *f();
3*f4a2713aSLionel Sambuc
g()4*f4a2713aSLionel Sambuc template <typename T> T* g() {
5*f4a2713aSLionel Sambuc if (T* t = f())
6*f4a2713aSLionel Sambuc return t;
7*f4a2713aSLionel Sambuc
8*f4a2713aSLionel Sambuc return 0;
9*f4a2713aSLionel Sambuc }
10*f4a2713aSLionel Sambuc
h()11*f4a2713aSLionel Sambuc void h() {
12*f4a2713aSLionel Sambuc void *a = g<void>();
13*f4a2713aSLionel Sambuc }
14*f4a2713aSLionel Sambuc
15*f4a2713aSLionel Sambuc struct X {
16*f4a2713aSLionel Sambuc X();
17*f4a2713aSLionel Sambuc X(const X&);
18*f4a2713aSLionel Sambuc ~X();
19*f4a2713aSLionel Sambuc operator bool();
20*f4a2713aSLionel Sambuc };
21*f4a2713aSLionel Sambuc
22*f4a2713aSLionel Sambuc struct Y {
23*f4a2713aSLionel Sambuc Y();
24*f4a2713aSLionel Sambuc ~Y();
25*f4a2713aSLionel Sambuc };
26*f4a2713aSLionel Sambuc
27*f4a2713aSLionel Sambuc X getX();
28*f4a2713aSLionel Sambuc
29*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_Z11if_destructi(
if_destruct(int z)30*f4a2713aSLionel Sambuc void if_destruct(int z) {
31*f4a2713aSLionel Sambuc // Verify that the condition variable is destroyed at the end of the
32*f4a2713aSLionel Sambuc // "if" statement.
33*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1Ev
34*f4a2713aSLionel Sambuc // CHECK: call zeroext i1 @_ZN1XcvbEv
35*f4a2713aSLionel Sambuc if (X x = X()) {
36*f4a2713aSLionel Sambuc // CHECK: store i32 18
37*f4a2713aSLionel Sambuc z = 18;
38*f4a2713aSLionel Sambuc }
39*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
40*f4a2713aSLionel Sambuc // CHECK: store i32 17
41*f4a2713aSLionel Sambuc z = 17;
42*f4a2713aSLionel Sambuc
43*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1Ev
44*f4a2713aSLionel Sambuc if (X x = X())
45*f4a2713aSLionel Sambuc Y y;
46*f4a2713aSLionel Sambuc // CHECK: br
47*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1YC1Ev
48*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1YD1Ev
49*f4a2713aSLionel Sambuc // CHECK: br
50*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
51*f4a2713aSLionel Sambuc
52*f4a2713aSLionel Sambuc // CHECK: call void @_Z4getXv
53*f4a2713aSLionel Sambuc // CHECK: call zeroext i1 @_ZN1XcvbEv
54*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
55*f4a2713aSLionel Sambuc // CHECK: br
56*f4a2713aSLionel Sambuc if (getX()) { }
57*f4a2713aSLionel Sambuc
58*f4a2713aSLionel Sambuc // CHECK: ret
59*f4a2713aSLionel Sambuc }
60*f4a2713aSLionel Sambuc
61*f4a2713aSLionel Sambuc struct ConvertibleToInt {
62*f4a2713aSLionel Sambuc ConvertibleToInt();
63*f4a2713aSLionel Sambuc ~ConvertibleToInt();
64*f4a2713aSLionel Sambuc operator int();
65*f4a2713aSLionel Sambuc };
66*f4a2713aSLionel Sambuc
67*f4a2713aSLionel Sambuc ConvertibleToInt getConvToInt();
68*f4a2713aSLionel Sambuc
switch_destruct(int z)69*f4a2713aSLionel Sambuc void switch_destruct(int z) {
70*f4a2713aSLionel Sambuc // CHECK: call void @_ZN16ConvertibleToIntC1Ev
71*f4a2713aSLionel Sambuc switch (ConvertibleToInt conv = ConvertibleToInt()) {
72*f4a2713aSLionel Sambuc case 0:
73*f4a2713aSLionel Sambuc break;
74*f4a2713aSLionel Sambuc
75*f4a2713aSLionel Sambuc default:
76*f4a2713aSLionel Sambuc // CHECK: store i32 19
77*f4a2713aSLionel Sambuc z = 19;
78*f4a2713aSLionel Sambuc break;
79*f4a2713aSLionel Sambuc }
80*f4a2713aSLionel Sambuc // CHECK: call void @_ZN16ConvertibleToIntD1Ev
81*f4a2713aSLionel Sambuc // CHECK: store i32 20
82*f4a2713aSLionel Sambuc z = 20;
83*f4a2713aSLionel Sambuc
84*f4a2713aSLionel Sambuc // CHECK: call void @_Z12getConvToIntv
85*f4a2713aSLionel Sambuc // CHECK: call i32 @_ZN16ConvertibleToIntcviEv
86*f4a2713aSLionel Sambuc // CHECK: call void @_ZN16ConvertibleToIntD1Ev
87*f4a2713aSLionel Sambuc switch(getConvToInt()) {
88*f4a2713aSLionel Sambuc case 0:
89*f4a2713aSLionel Sambuc break;
90*f4a2713aSLionel Sambuc }
91*f4a2713aSLionel Sambuc // CHECK: store i32 27
92*f4a2713aSLionel Sambuc z = 27;
93*f4a2713aSLionel Sambuc // CHECK: ret
94*f4a2713aSLionel Sambuc }
95*f4a2713aSLionel Sambuc
96*f4a2713aSLionel Sambuc int foo();
97*f4a2713aSLionel Sambuc
98*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_Z14while_destructi
while_destruct(int z)99*f4a2713aSLionel Sambuc void while_destruct(int z) {
100*f4a2713aSLionel Sambuc // CHECK: [[Z:%.*]] = alloca i32
101*f4a2713aSLionel Sambuc // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
102*f4a2713aSLionel Sambuc while (X x = X()) {
103*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1Ev
104*f4a2713aSLionel Sambuc // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv
105*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[COND]]
106*f4a2713aSLionel Sambuc
107*f4a2713aSLionel Sambuc // Loop-exit staging block.
108*f4a2713aSLionel Sambuc // CHECK: store i32 3, i32* [[CLEANUPDEST]]
109*f4a2713aSLionel Sambuc // CHECK-NEXT: br
110*f4a2713aSLionel Sambuc
111*f4a2713aSLionel Sambuc // While body.
112*f4a2713aSLionel Sambuc // CHECK: store i32 21, i32* [[Z]]
113*f4a2713aSLionel Sambuc // CHECK: store i32 0, i32* [[CLEANUPDEST]]
114*f4a2713aSLionel Sambuc // CHECK-NEXT: br
115*f4a2713aSLionel Sambuc z = 21;
116*f4a2713aSLionel Sambuc
117*f4a2713aSLionel Sambuc // Cleanup.
118*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
119*f4a2713aSLionel Sambuc // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]]
120*f4a2713aSLionel Sambuc // CHECK-NEXT: switch i32 [[DEST]]
121*f4a2713aSLionel Sambuc }
122*f4a2713aSLionel Sambuc
123*f4a2713aSLionel Sambuc // CHECK: store i32 22, i32* [[Z]]
124*f4a2713aSLionel Sambuc z = 22;
125*f4a2713aSLionel Sambuc
126*f4a2713aSLionel Sambuc // CHECK: call void @_Z4getXv
127*f4a2713aSLionel Sambuc // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
128*f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN1XD1Ev
129*f4a2713aSLionel Sambuc // CHECK-NEXT: br
130*f4a2713aSLionel Sambuc while(getX()) { }
131*f4a2713aSLionel Sambuc
132*f4a2713aSLionel Sambuc // CHECK: store i32 25, i32* [[Z]]
133*f4a2713aSLionel Sambuc z = 25;
134*f4a2713aSLionel Sambuc
135*f4a2713aSLionel Sambuc // CHECK: ret
136*f4a2713aSLionel Sambuc }
137*f4a2713aSLionel Sambuc
138*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_Z12for_destructi(
for_destruct(int z)139*f4a2713aSLionel Sambuc void for_destruct(int z) {
140*f4a2713aSLionel Sambuc // CHECK: [[Z:%.*]] = alloca i32
141*f4a2713aSLionel Sambuc // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
142*f4a2713aSLionel Sambuc // CHECK: [[I:%.*]] = alloca i32
143*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1YC1Ev
144*f4a2713aSLionel Sambuc // CHECK-NEXT: br
145*f4a2713aSLionel Sambuc // -> %for.cond
146*f4a2713aSLionel Sambuc
147*f4a2713aSLionel Sambuc for(Y y = Y(); X x = X(); ++z) {
148*f4a2713aSLionel Sambuc // %for.cond: The loop condition.
149*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1Ev
150*f4a2713aSLionel Sambuc // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv(
151*f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[COND]]
152*f4a2713aSLionel Sambuc // -> %for.body, %for.cond.cleanup
153*f4a2713aSLionel Sambuc
154*f4a2713aSLionel Sambuc // %for.cond.cleanup: Exit cleanup staging.
155*f4a2713aSLionel Sambuc // CHECK: store i32 2, i32* [[CLEANUPDEST]]
156*f4a2713aSLionel Sambuc // CHECK-NEXT: br
157*f4a2713aSLionel Sambuc // -> %cleanup
158*f4a2713aSLionel Sambuc
159*f4a2713aSLionel Sambuc // %for.body:
160*f4a2713aSLionel Sambuc // CHECK: store i32 23, i32* [[Z]]
161*f4a2713aSLionel Sambuc // CHECK-NEXT: br
162*f4a2713aSLionel Sambuc // -> %for.inc
163*f4a2713aSLionel Sambuc z = 23;
164*f4a2713aSLionel Sambuc
165*f4a2713aSLionel Sambuc // %for.inc:
166*f4a2713aSLionel Sambuc // CHECK: [[TMP:%.*]] = load i32* [[Z]]
167*f4a2713aSLionel Sambuc // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
168*f4a2713aSLionel Sambuc // CHECK-NEXT: store i32 [[INC]], i32* [[Z]]
169*f4a2713aSLionel Sambuc // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]]
170*f4a2713aSLionel Sambuc // CHECK-NEXT: br
171*f4a2713aSLionel Sambuc // -> %cleanup
172*f4a2713aSLionel Sambuc
173*f4a2713aSLionel Sambuc // %cleanup: Destroys X.
174*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
175*f4a2713aSLionel Sambuc // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]]
176*f4a2713aSLionel Sambuc // CHECK-NEXT: switch i32 [[YDESTTMP]]
177*f4a2713aSLionel Sambuc // 0 -> %cleanup.cont, default -> %cleanup1
178*f4a2713aSLionel Sambuc
179*f4a2713aSLionel Sambuc // %cleanup.cont: (eliminable)
180*f4a2713aSLionel Sambuc // CHECK: br
181*f4a2713aSLionel Sambuc // -> %for.cond
182*f4a2713aSLionel Sambuc
183*f4a2713aSLionel Sambuc // %cleanup1: Destroys Y.
184*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1YD1Ev(
185*f4a2713aSLionel Sambuc // CHECK-NEXT: br
186*f4a2713aSLionel Sambuc // -> %for.end
187*f4a2713aSLionel Sambuc }
188*f4a2713aSLionel Sambuc
189*f4a2713aSLionel Sambuc // %for.end:
190*f4a2713aSLionel Sambuc // CHECK: store i32 24
191*f4a2713aSLionel Sambuc z = 24;
192*f4a2713aSLionel Sambuc
193*f4a2713aSLionel Sambuc // CHECK-NEXT: store i32 0, i32* [[I]]
194*f4a2713aSLionel Sambuc // CHECK-NEXT: br
195*f4a2713aSLionel Sambuc // -> %for.cond6
196*f4a2713aSLionel Sambuc
197*f4a2713aSLionel Sambuc // %for.cond6:
198*f4a2713aSLionel Sambuc // CHECK: call void @_Z4getXv
199*f4a2713aSLionel Sambuc // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
200*f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN1XD1Ev
201*f4a2713aSLionel Sambuc // CHECK-NEXT: br
202*f4a2713aSLionel Sambuc // -> %for.body10, %for.end16
203*f4a2713aSLionel Sambuc
204*f4a2713aSLionel Sambuc // %for.body10:
205*f4a2713aSLionel Sambuc // CHECK: br
206*f4a2713aSLionel Sambuc // -> %for.inc11
207*f4a2713aSLionel Sambuc
208*f4a2713aSLionel Sambuc // %for.inc11:
209*f4a2713aSLionel Sambuc // CHECK: call void @_Z4getXv
210*f4a2713aSLionel Sambuc // CHECK-NEXT: load i32* [[I]]
211*f4a2713aSLionel Sambuc // CHECK-NEXT: add
212*f4a2713aSLionel Sambuc // CHECK-NEXT: store
213*f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN1XD1Ev
214*f4a2713aSLionel Sambuc // CHECK-NEXT: br
215*f4a2713aSLionel Sambuc // -> %for.cond6
216*f4a2713aSLionel Sambuc int i = 0;
217*f4a2713aSLionel Sambuc for(; getX(); getX(), ++i) { }
218*f4a2713aSLionel Sambuc
219*f4a2713aSLionel Sambuc // %for.end16
220*f4a2713aSLionel Sambuc // CHECK: store i32 26
221*f4a2713aSLionel Sambuc z = 26;
222*f4a2713aSLionel Sambuc
223*f4a2713aSLionel Sambuc // CHECK-NEXT: ret void
224*f4a2713aSLionel Sambuc }
225*f4a2713aSLionel Sambuc
do_destruct(int z)226*f4a2713aSLionel Sambuc void do_destruct(int z) {
227*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_Z11do_destruct
228*f4a2713aSLionel Sambuc do {
229*f4a2713aSLionel Sambuc // CHECK: store i32 77
230*f4a2713aSLionel Sambuc z = 77;
231*f4a2713aSLionel Sambuc // CHECK: call void @_Z4getXv
232*f4a2713aSLionel Sambuc // CHECK: call zeroext i1 @_ZN1XcvbEv
233*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
234*f4a2713aSLionel Sambuc // CHECK: br
235*f4a2713aSLionel Sambuc } while (getX());
236*f4a2713aSLionel Sambuc // CHECK: store i32 99
237*f4a2713aSLionel Sambuc z = 99;
238*f4a2713aSLionel Sambuc // CHECK: ret
239*f4a2713aSLionel Sambuc }
240*f4a2713aSLionel Sambuc
241*f4a2713aSLionel Sambuc int f(X);
242*f4a2713aSLionel Sambuc
243*f4a2713aSLionel Sambuc template<typename T>
instantiated(T x)244*f4a2713aSLionel Sambuc int instantiated(T x) {
245*f4a2713aSLionel Sambuc int result;
246*f4a2713aSLionel Sambuc
247*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
248*f4a2713aSLionel Sambuc // CHECK: call i32 @_Z1f1X
249*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
250*f4a2713aSLionel Sambuc // CHECK: br
251*f4a2713aSLionel Sambuc // CHECK: store i32 2
252*f4a2713aSLionel Sambuc // CHECK: br
253*f4a2713aSLionel Sambuc // CHECK: store i32 3
254*f4a2713aSLionel Sambuc if (f(x)) { result = 2; } else { result = 3; }
255*f4a2713aSLionel Sambuc
256*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
257*f4a2713aSLionel Sambuc // CHECK: call i32 @_Z1f1X
258*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
259*f4a2713aSLionel Sambuc // CHECK: br
260*f4a2713aSLionel Sambuc // CHECK: store i32 4
261*f4a2713aSLionel Sambuc // CHECK: br
262*f4a2713aSLionel Sambuc while (f(x)) { result = 4; }
263*f4a2713aSLionel Sambuc
264*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
265*f4a2713aSLionel Sambuc // CHECK: call i32 @_Z1f1X
266*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
267*f4a2713aSLionel Sambuc // CHECK: br
268*f4a2713aSLionel Sambuc // CHECK: store i32 6
269*f4a2713aSLionel Sambuc // CHECK: br
270*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
271*f4a2713aSLionel Sambuc // CHECK: call i32 @_Z1f1X
272*f4a2713aSLionel Sambuc // CHECK: store i32 5
273*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
274*f4a2713aSLionel Sambuc // CHECK: br
275*f4a2713aSLionel Sambuc for (; f(x); f(x), result = 5) {
276*f4a2713aSLionel Sambuc result = 6;
277*f4a2713aSLionel Sambuc }
278*f4a2713aSLionel Sambuc
279*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
280*f4a2713aSLionel Sambuc // CHECK: call i32 @_Z1f1X
281*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
282*f4a2713aSLionel Sambuc // CHECK: switch i32
283*f4a2713aSLionel Sambuc // CHECK: store i32 7
284*f4a2713aSLionel Sambuc // CHECK: store i32 8
285*f4a2713aSLionel Sambuc switch (f(x)) {
286*f4a2713aSLionel Sambuc case 0:
287*f4a2713aSLionel Sambuc result = 7;
288*f4a2713aSLionel Sambuc break;
289*f4a2713aSLionel Sambuc
290*f4a2713aSLionel Sambuc case 1:
291*f4a2713aSLionel Sambuc result = 8;
292*f4a2713aSLionel Sambuc }
293*f4a2713aSLionel Sambuc
294*f4a2713aSLionel Sambuc // CHECK: store i32 9
295*f4a2713aSLionel Sambuc // CHECK: br
296*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
297*f4a2713aSLionel Sambuc // CHECK: call i32 @_Z1f1X
298*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
299*f4a2713aSLionel Sambuc // CHECK: br
300*f4a2713aSLionel Sambuc do {
301*f4a2713aSLionel Sambuc result = 9;
302*f4a2713aSLionel Sambuc } while (f(x));
303*f4a2713aSLionel Sambuc
304*f4a2713aSLionel Sambuc // CHECK: store i32 10
305*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XC1ERKS_
306*f4a2713aSLionel Sambuc // CHECK: call zeroext i1 @_ZN1XcvbEv
307*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1XD1Ev
308*f4a2713aSLionel Sambuc // CHECK: br
309*f4a2713aSLionel Sambuc do {
310*f4a2713aSLionel Sambuc result = 10;
311*f4a2713aSLionel Sambuc } while (X(x));
312*f4a2713aSLionel Sambuc
313*f4a2713aSLionel Sambuc // CHECK: ret i32
314*f4a2713aSLionel Sambuc return result;
315*f4a2713aSLionel Sambuc }
316*f4a2713aSLionel Sambuc
317*f4a2713aSLionel Sambuc template int instantiated(X);
318