blob: cc2eaf5bd6a5ecd010aeb4e5df8cf1fdaea3c2dc [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
Douglas Gregor01234bb2009-11-24 16:43:22 +00002void *f();
3
4template <typename T> T* g() {
5 if (T* t = f())
6 return t;
7
8 return 0;
9}
10
11void h() {
12 void *a = g<void>();
13}
14
15struct X {
16 X();
Douglas Gregoreaa18e42010-05-08 22:20:28 +000017 X(const X&);
Douglas Gregor01234bb2009-11-24 16:43:22 +000018 ~X();
19 operator bool();
20};
21
22struct Y {
23 Y();
24 ~Y();
25};
26
Douglas Gregor586596f2010-05-06 17:25:47 +000027X getX();
28
John McCallda65ea82010-07-13 20:32:21 +000029// CHECK: define void @_Z11if_destructi(
Douglas Gregor01234bb2009-11-24 16:43:22 +000030void 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;
Mike Stumpedc95e72010-01-13 20:57:29 +000046 // CHECK: br
Douglas Gregor01234bb2009-11-24 16:43:22 +000047 // CHECK: call void @_ZN1YC1Ev
48 // CHECK: call void @_ZN1YD1Ev
Mike Stumpedc95e72010-01-13 20:57:29 +000049 // CHECK: br
Douglas Gregor01234bb2009-11-24 16:43:22 +000050 // CHECK: call void @_ZN1XD1Ev
Douglas Gregor586596f2010-05-06 17:25:47 +000051
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
Douglas Gregor01234bb2009-11-24 16:43:22 +000059}
Douglas Gregord3d53012009-11-24 17:07:59 +000060
61struct ConvertibleToInt {
62 ConvertibleToInt();
63 ~ConvertibleToInt();
64 operator int();
65};
66
Douglas Gregor586596f2010-05-06 17:25:47 +000067ConvertibleToInt getConvToInt();
68
Douglas Gregord3d53012009-11-24 17:07:59 +000069void switch_destruct(int z) {
70 // CHECK: call void @_ZN16ConvertibleToIntC1Ev
71 switch (ConvertibleToInt conv = ConvertibleToInt()) {
72 case 0:
73 break;
74
75 default:
Douglas Gregord3d53012009-11-24 17:07:59 +000076 // CHECK: store i32 19
77 z = 19;
78 break;
79 }
Douglas Gregord3d53012009-11-24 17:07:59 +000080 // CHECK: call void @_ZN16ConvertibleToIntD1Ev
81 // CHECK: store i32 20
82 z = 20;
Douglas Gregor586596f2010-05-06 17:25:47 +000083
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
Douglas Gregord3d53012009-11-24 17:07:59 +000094}
Douglas Gregor5656e142009-11-24 21:15:44 +000095
96int foo();
97
John McCallf1549f62010-07-06 01:34:17 +000098// CHECK: define void @_Z14while_destructi
Douglas Gregor5656e142009-11-24 21:15:44 +000099void while_destruct(int z) {
John McCallf1549f62010-07-06 01:34:17 +0000100 // CHECK: [[Z:%.*]] = alloca i32
101 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
Douglas Gregor5656e142009-11-24 21:15:44 +0000102 while (X x = X()) {
103 // CHECK: call void @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +0000104 // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv
105 // CHECK-NEXT: br i1 [[COND]]
Douglas Gregor5656e142009-11-24 21:15:44 +0000106
John McCallf1549f62010-07-06 01:34:17 +0000107 // Loop-exit staging block.
John McCallff8e1152010-07-23 21:56:41 +0000108 // CHECK: store i32 3, i32* [[CLEANUPDEST]]
John McCallf1549f62010-07-06 01:34:17 +0000109 // CHECK-NEXT: br
110
111 // While body.
112 // CHECK: store i32 21, i32* [[Z]]
John McCallff8e1152010-07-23 21:56:41 +0000113 // CHECK: store i32 0, i32* [[CLEANUPDEST]]
John McCallf1549f62010-07-06 01:34:17 +0000114 // CHECK-NEXT: br
Douglas Gregor5656e142009-11-24 21:15:44 +0000115 z = 21;
116
John McCallf1549f62010-07-06 01:34:17 +0000117 // Cleanup.
Douglas Gregor5656e142009-11-24 21:15:44 +0000118 // CHECK: call void @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +0000119 // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]]
120 // CHECK-NEXT: switch i32 [[DEST]]
Douglas Gregor5656e142009-11-24 21:15:44 +0000121 }
John McCallf1549f62010-07-06 01:34:17 +0000122
123 // CHECK: store i32 22, i32* [[Z]]
Douglas Gregor5656e142009-11-24 21:15:44 +0000124 z = 22;
Douglas Gregor586596f2010-05-06 17:25:47 +0000125
126 // CHECK: call void @_Z4getXv
John McCallf1549f62010-07-06 01:34:17 +0000127 // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
128 // CHECK-NEXT: call void @_ZN1XD1Ev
129 // CHECK-NEXT: br
Douglas Gregor586596f2010-05-06 17:25:47 +0000130 while(getX()) { }
131
John McCallf1549f62010-07-06 01:34:17 +0000132 // CHECK: store i32 25, i32* [[Z]]
Douglas Gregor586596f2010-05-06 17:25:47 +0000133 z = 25;
134
135 // CHECK: ret
Douglas Gregor5656e142009-11-24 21:15:44 +0000136}
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000137
John McCallf1549f62010-07-06 01:34:17 +0000138// CHECK: define void @_Z12for_destructi(
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000139void for_destruct(int z) {
John McCallf1549f62010-07-06 01:34:17 +0000140 // CHECK: [[Z:%.*]] = alloca i32
John McCallff8e1152010-07-23 21:56:41 +0000141 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
John McCallf1549f62010-07-06 01:34:17 +0000142 // CHECK: [[I:%.*]] = alloca i32
Douglas Gregor345e7d22009-11-25 00:29:29 +0000143 // CHECK: call void @_ZN1YC1Ev
John McCallf1549f62010-07-06 01:34:17 +0000144 // CHECK-NEXT: br
145 // -> %for.cond
146
147 for(Y y = Y(); X x = X(); ++z) {
148 // %for.cond: The loop condition.
Douglas Gregord9752062009-11-25 01:51:31 +0000149 // CHECK: call void @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +0000150 // 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.
John McCallff8e1152010-07-23 21:56:41 +0000155 // CHECK: store i32 2, i32* [[CLEANUPDEST]]
John McCallf1549f62010-07-06 01:34:17 +0000156 // CHECK-NEXT: br
157 // -> %cleanup
158
159 // %for.body:
160 // CHECK: store i32 23, i32* [[Z]]
161 // CHECK-NEXT: br
162 // -> %for.inc
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000163 z = 23;
John McCallf1549f62010-07-06 01:34:17 +0000164
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]]
John McCallff8e1152010-07-23 21:56:41 +0000169 // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]]
John McCallf1549f62010-07-06 01:34:17 +0000170 // CHECK-NEXT: br
171 // -> %cleanup
172
173 // %cleanup: Destroys X.
Douglas Gregord9752062009-11-25 01:51:31 +0000174 // CHECK: call void @_ZN1XD1Ev
John McCallff8e1152010-07-23 21:56:41 +0000175 // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]]
John McCallf1549f62010-07-06 01:34:17 +0000176 // CHECK-NEXT: switch i32 [[YDESTTMP]]
John McCallff8e1152010-07-23 21:56:41 +0000177 // 0 -> %cleanup.cont, default -> %cleanup1
John McCallf1549f62010-07-06 01:34:17 +0000178
179 // %cleanup.cont: (eliminable)
180 // CHECK: br
181 // -> %for.cond
182
John McCallff8e1152010-07-23 21:56:41 +0000183 // %cleanup1: Destroys Y.
John McCallf1549f62010-07-06 01:34:17 +0000184 // CHECK: call void @_ZN1YD1Ev(
185 // CHECK-NEXT: br
186 // -> %for.end
187 }
188
189 // %for.end:
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000190 // CHECK: store i32 24
191 z = 24;
Douglas Gregor586596f2010-05-06 17:25:47 +0000192
John McCallf1549f62010-07-06 01:34:17 +0000193 // CHECK-NEXT: store i32 0, i32* [[I]]
194 // CHECK-NEXT: br
195 // -> %for.cond6
196
197 // %for.cond6:
Douglas Gregor586596f2010-05-06 17:25:47 +0000198 // CHECK: call void @_Z4getXv
John McCallf1549f62010-07-06 01:34:17 +0000199 // 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:
Douglas Gregor586596f2010-05-06 17:25:47 +0000205 // CHECK: br
John McCallf1549f62010-07-06 01:34:17 +0000206 // -> %for.inc11
207
208 // %for.inc11:
Douglas Gregor586596f2010-05-06 17:25:47 +0000209 // CHECK: call void @_Z4getXv
John McCallf1549f62010-07-06 01:34:17 +0000210 // 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
Douglas Gregor586596f2010-05-06 17:25:47 +0000216 int i = 0;
217 for(; getX(); getX(), ++i) { }
John McCallf1549f62010-07-06 01:34:17 +0000218
219 // %for.end16
Douglas Gregor586596f2010-05-06 17:25:47 +0000220 // CHECK: store i32 26
John McCallf1549f62010-07-06 01:34:17 +0000221 z = 26;
222
223 // CHECK-NEXT: ret void
Douglas Gregor586596f2010-05-06 17:25:47 +0000224}
225
226void do_destruct(int z) {
227 // CHECK: 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
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000239}
Douglas Gregoreaa18e42010-05-08 22:20:28 +0000240
241int f(X);
242
243template<typename T>
244int 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
317template int instantiated(X);