• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
2 void *f();
3 
g()4 template <typename T> T* g() {
5  if (T* t = f())
6    return t;
7 
8  return 0;
9 }
10 
h()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(
if_destruct(int z)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 
switch_destruct(int z)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
while_destruct(int z)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, 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(
for_destruct(int z)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, 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, 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, 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 
do_destruct(int z)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>
instantiated(T x)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);
318