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