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