]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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: 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: 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: 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: 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); |