blob: b1fa9f1c80a3cfe250fa1efac4bef7a3bd089b14 [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
Douglas Gregor01234bb2009-11-24 16:43:22 +000029void if_destruct(int z) {
30 // Verify that the condition variable is destroyed at the end of the
31 // "if" statement.
32 // CHECK: call void @_ZN1XC1Ev
33 // CHECK: call zeroext i1 @_ZN1XcvbEv
34 if (X x = X()) {
35 // CHECK: store i32 18
36 z = 18;
37 }
38 // CHECK: call void @_ZN1XD1Ev
39 // CHECK: store i32 17
40 z = 17;
41
42 // CHECK: call void @_ZN1XC1Ev
43 if (X x = X())
44 Y y;
Mike Stumpedc95e72010-01-13 20:57:29 +000045 // CHECK: br
Douglas Gregor01234bb2009-11-24 16:43:22 +000046 // CHECK: call void @_ZN1YC1Ev
47 // CHECK: call void @_ZN1YD1Ev
Mike Stumpedc95e72010-01-13 20:57:29 +000048 // CHECK: br
Douglas Gregor01234bb2009-11-24 16:43:22 +000049 // CHECK: call void @_ZN1XD1Ev
Douglas Gregor586596f2010-05-06 17:25:47 +000050
51 // CHECK: call void @_Z4getXv
52 // CHECK: call zeroext i1 @_ZN1XcvbEv
53 // CHECK: call void @_ZN1XD1Ev
54 // CHECK: br
55 if (getX()) { }
56
57 // CHECK: ret
Douglas Gregor01234bb2009-11-24 16:43:22 +000058}
Douglas Gregord3d53012009-11-24 17:07:59 +000059
60struct ConvertibleToInt {
61 ConvertibleToInt();
62 ~ConvertibleToInt();
63 operator int();
64};
65
Douglas Gregor586596f2010-05-06 17:25:47 +000066ConvertibleToInt getConvToInt();
67
Douglas Gregord3d53012009-11-24 17:07:59 +000068void switch_destruct(int z) {
69 // CHECK: call void @_ZN16ConvertibleToIntC1Ev
70 switch (ConvertibleToInt conv = ConvertibleToInt()) {
71 case 0:
72 break;
73
74 default:
Douglas Gregor40e62992010-05-08 16:04:01 +000075 // CHECK: {{sw.default:|:5}}
Douglas Gregord3d53012009-11-24 17:07:59 +000076 // CHECK: store i32 19
77 z = 19;
78 break;
79 }
Douglas Gregor40e62992010-05-08 16:04:01 +000080 // CHECK: {{sw.epilog:|:6}}
Douglas Gregord3d53012009-11-24 17:07:59 +000081 // CHECK: call void @_ZN16ConvertibleToIntD1Ev
82 // CHECK: store i32 20
83 z = 20;
Douglas Gregor586596f2010-05-06 17:25:47 +000084
85 // CHECK: call void @_Z12getConvToIntv
86 // CHECK: call i32 @_ZN16ConvertibleToIntcviEv
87 // CHECK: call void @_ZN16ConvertibleToIntD1Ev
88 switch(getConvToInt()) {
89 case 0:
90 break;
91 }
92 // CHECK: store i32 27
93 z = 27;
94 // CHECK: ret
Douglas Gregord3d53012009-11-24 17:07:59 +000095}
Douglas Gregor5656e142009-11-24 21:15:44 +000096
97int foo();
98
John McCallf1549f62010-07-06 01:34:17 +000099// CHECK: define void @_Z14while_destructi
Douglas Gregor5656e142009-11-24 21:15:44 +0000100void while_destruct(int z) {
John McCallf1549f62010-07-06 01:34:17 +0000101 // CHECK: [[Z:%.*]] = alloca i32
102 // CHECK: [[CLEANUPDEST:%.*]] = alloca i32
Douglas Gregor5656e142009-11-24 21:15:44 +0000103 while (X x = X()) {
104 // CHECK: call void @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +0000105 // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv
106 // CHECK-NEXT: br i1 [[COND]]
Douglas Gregor5656e142009-11-24 21:15:44 +0000107
John McCallf1549f62010-07-06 01:34:17 +0000108 // Loop-exit staging block.
109 // CHECK: store i32 1, i32* [[CLEANUPDEST]]
110 // CHECK-NEXT: br
111
112 // While body.
113 // CHECK: store i32 21, i32* [[Z]]
114 // CHECK: store i32 2, i32* [[CLEANUPDEST]]
115 // CHECK-NEXT: br
Douglas Gregor5656e142009-11-24 21:15:44 +0000116 z = 21;
117
John McCallf1549f62010-07-06 01:34:17 +0000118 // Cleanup.
Douglas Gregor5656e142009-11-24 21:15:44 +0000119 // CHECK: call void @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +0000120 // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]]
121 // CHECK-NEXT: switch i32 [[DEST]]
Douglas Gregor5656e142009-11-24 21:15:44 +0000122 }
John McCallf1549f62010-07-06 01:34:17 +0000123
124 // CHECK: store i32 22, i32* [[Z]]
Douglas Gregor5656e142009-11-24 21:15:44 +0000125 z = 22;
Douglas Gregor586596f2010-05-06 17:25:47 +0000126
127 // CHECK: call void @_Z4getXv
John McCallf1549f62010-07-06 01:34:17 +0000128 // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
129 // CHECK-NEXT: call void @_ZN1XD1Ev
130 // CHECK-NEXT: br
Douglas Gregor586596f2010-05-06 17:25:47 +0000131 while(getX()) { }
132
John McCallf1549f62010-07-06 01:34:17 +0000133 // CHECK: store i32 25, i32* [[Z]]
Douglas Gregor586596f2010-05-06 17:25:47 +0000134 z = 25;
135
136 // CHECK: ret
Douglas Gregor5656e142009-11-24 21:15:44 +0000137}
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000138
John McCallf1549f62010-07-06 01:34:17 +0000139// CHECK: define void @_Z12for_destructi(
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000140void for_destruct(int z) {
John McCallf1549f62010-07-06 01:34:17 +0000141 // CHECK: [[Z:%.*]] = alloca i32
142 // CHECK: [[XDEST:%.*]] = alloca i32
143 // CHECK: [[I:%.*]] = alloca i32
Douglas Gregor345e7d22009-11-25 00:29:29 +0000144 // CHECK: call void @_ZN1YC1Ev
John McCallf1549f62010-07-06 01:34:17 +0000145 // CHECK-NEXT: br
146 // -> %for.cond
147
148 for(Y y = Y(); X x = X(); ++z) {
149 // %for.cond: The loop condition.
Douglas Gregord9752062009-11-25 01:51:31 +0000150 // CHECK: call void @_ZN1XC1Ev
John McCallf1549f62010-07-06 01:34:17 +0000151 // CHECK-NEXT: [[COND:%.*]] = call zeroext i1 @_ZN1XcvbEv(
152 // CHECK-NEXT: br i1 [[COND]]
153 // -> %for.body, %for.cond.cleanup
154
155 // %for.cond.cleanup: Exit cleanup staging.
156 // CHECK: store i32 1, i32* [[XDEST]]
157 // CHECK-NEXT: br
158 // -> %cleanup
159
160 // %for.body:
161 // CHECK: store i32 23, i32* [[Z]]
162 // CHECK-NEXT: br
163 // -> %for.inc
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000164 z = 23;
John McCallf1549f62010-07-06 01:34:17 +0000165
166 // %for.inc:
167 // CHECK: [[TMP:%.*]] = load i32* [[Z]]
168 // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1
169 // CHECK-NEXT: store i32 [[INC]], i32* [[Z]]
170 // CHECK-NEXT: store i32 2, i32* [[XDEST]]
171 // CHECK-NEXT: br
172 // -> %cleanup
173
174 // %cleanup: Destroys X.
Douglas Gregord9752062009-11-25 01:51:31 +0000175 // CHECK: call void @_ZN1XD1Ev
John McCallf1549f62010-07-06 01:34:17 +0000176 // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[XDEST]]
177 // CHECK-NEXT: switch i32 [[YDESTTMP]]
178 // 1 -> %cleanup4, 2 -> %cleanup.cont
179
180 // %cleanup.cont: (eliminable)
181 // CHECK: br
182 // -> %for.cond
183
184 // %cleanup4: Destroys Y.
185 // CHECK: call void @_ZN1YD1Ev(
186 // CHECK-NEXT: br
187 // -> %for.end
188 }
189
190 // %for.end:
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000191 // CHECK: store i32 24
192 z = 24;
Douglas Gregor586596f2010-05-06 17:25:47 +0000193
John McCallf1549f62010-07-06 01:34:17 +0000194 // CHECK-NEXT: store i32 0, i32* [[I]]
195 // CHECK-NEXT: br
196 // -> %for.cond6
197
198 // %for.cond6:
Douglas Gregor586596f2010-05-06 17:25:47 +0000199 // CHECK: call void @_Z4getXv
John McCallf1549f62010-07-06 01:34:17 +0000200 // CHECK-NEXT: call zeroext i1 @_ZN1XcvbEv
201 // CHECK-NEXT: call void @_ZN1XD1Ev
202 // CHECK-NEXT: br
203 // -> %for.body10, %for.end16
204
205 // %for.body10:
Douglas Gregor586596f2010-05-06 17:25:47 +0000206 // CHECK: br
John McCallf1549f62010-07-06 01:34:17 +0000207 // -> %for.inc11
208
209 // %for.inc11:
Douglas Gregor586596f2010-05-06 17:25:47 +0000210 // CHECK: call void @_Z4getXv
John McCallf1549f62010-07-06 01:34:17 +0000211 // CHECK-NEXT: load i32* [[I]]
212 // CHECK-NEXT: add
213 // CHECK-NEXT: store
214 // CHECK-NEXT: call void @_ZN1XD1Ev
215 // CHECK-NEXT: br
216 // -> %for.cond6
Douglas Gregor586596f2010-05-06 17:25:47 +0000217 int i = 0;
218 for(; getX(); getX(), ++i) { }
John McCallf1549f62010-07-06 01:34:17 +0000219
220 // %for.end16
Douglas Gregor586596f2010-05-06 17:25:47 +0000221 // CHECK: store i32 26
John McCallf1549f62010-07-06 01:34:17 +0000222 z = 26;
223
224 // CHECK-NEXT: ret void
Douglas Gregor586596f2010-05-06 17:25:47 +0000225}
226
227void do_destruct(int z) {
228 // CHECK: define void @_Z11do_destruct
229 do {
230 // CHECK: store i32 77
231 z = 77;
232 // CHECK: call void @_Z4getXv
233 // CHECK: call zeroext i1 @_ZN1XcvbEv
234 // CHECK: call void @_ZN1XD1Ev
235 // CHECK: br
236 } while (getX());
237 // CHECK: store i32 99
238 z = 99;
239 // CHECK: ret
Douglas Gregor99e9b4d2009-11-25 00:27:52 +0000240}
Douglas Gregoreaa18e42010-05-08 22:20:28 +0000241
242int f(X);
243
244template<typename T>
245int instantiated(T x) {
246 int result;
247
248 // CHECK: call void @_ZN1XC1ERKS_
249 // CHECK: call i32 @_Z1f1X
250 // CHECK: call void @_ZN1XD1Ev
251 // CHECK: br
252 // CHECK: store i32 2
253 // CHECK: br
254 // CHECK: store i32 3
255 if (f(x)) { result = 2; } else { result = 3; }
256
257 // CHECK: call void @_ZN1XC1ERKS_
258 // CHECK: call i32 @_Z1f1X
259 // CHECK: call void @_ZN1XD1Ev
260 // CHECK: br
261 // CHECK: store i32 4
262 // CHECK: br
263 while (f(x)) { result = 4; }
264
265 // CHECK: call void @_ZN1XC1ERKS_
266 // CHECK: call i32 @_Z1f1X
267 // CHECK: call void @_ZN1XD1Ev
268 // CHECK: br
269 // CHECK: store i32 6
270 // CHECK: br
271 // CHECK: call void @_ZN1XC1ERKS_
272 // CHECK: call i32 @_Z1f1X
273 // CHECK: store i32 5
274 // CHECK: call void @_ZN1XD1Ev
275 // CHECK: br
276 for (; f(x); f(x), result = 5) {
277 result = 6;
278 }
279
280 // CHECK: call void @_ZN1XC1ERKS_
281 // CHECK: call i32 @_Z1f1X
282 // CHECK: call void @_ZN1XD1Ev
283 // CHECK: switch i32
284 // CHECK: store i32 7
285 // CHECK: store i32 8
286 switch (f(x)) {
287 case 0:
288 result = 7;
289 break;
290
291 case 1:
292 result = 8;
293 }
294
295 // CHECK: store i32 9
296 // CHECK: br
297 // CHECK: call void @_ZN1XC1ERKS_
298 // CHECK: call i32 @_Z1f1X
299 // CHECK: call void @_ZN1XD1Ev
300 // CHECK: br
301 do {
302 result = 9;
303 } while (f(x));
304
305 // CHECK: store i32 10
306 // CHECK: call void @_ZN1XC1ERKS_
307 // CHECK: call zeroext i1 @_ZN1XcvbEv
308 // CHECK: call void @_ZN1XD1Ev
309 // CHECK: br
310 do {
311 result = 10;
312 } while (X(x));
313
314 // CHECK: ret i32
315 return result;
316}
317
318template int instantiated(X);