condition.cpp revision eaa18e449bb09c1e580aa35f9606ff2ca682f4cb
1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
2void *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();
17  X(const X&);
18  ~X();
19  operator bool();
20};
21
22struct Y {
23  Y();
24  ~Y();
25};
26
27X getX();
28
29void 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;
45  // CHECK: br
46  // CHECK: call  void @_ZN1YC1Ev
47  // CHECK: call  void @_ZN1YD1Ev
48  // CHECK: br
49  // CHECK: call  void @_ZN1XD1Ev
50
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
58}
59
60struct ConvertibleToInt {
61  ConvertibleToInt();
62  ~ConvertibleToInt();
63  operator int();
64};
65
66ConvertibleToInt getConvToInt();
67
68void switch_destruct(int z) {
69  // CHECK: call void @_ZN16ConvertibleToIntC1Ev
70  switch (ConvertibleToInt conv = ConvertibleToInt()) {
71  case 0:
72    break;
73
74  default:
75    // CHECK: {{sw.default:|:5}}
76    // CHECK: store i32 19
77    z = 19;
78    break;
79  }
80  // CHECK: {{sw.epilog:|:6}}
81  // CHECK: call void @_ZN16ConvertibleToIntD1Ev
82  // CHECK: store i32 20
83  z = 20;
84
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
95}
96
97int foo();
98
99void while_destruct(int z) {
100  // CHECK: define void @_Z14while_destructi
101  // CHECK: {{while.cond:|:3}}
102  while (X x = X()) {
103    // CHECK: call void @_ZN1XC1Ev
104
105    // CHECK: {{while.body:|:5}}
106    // CHECK: store i32 21
107    z = 21;
108
109    // CHECK: {{while.cleanup:|:6}}
110    // CHECK: call void @_ZN1XD1Ev
111  }
112  // CHECK: {{while.end|:8}}
113  // CHECK: store i32 22
114  z = 22;
115
116  // CHECK: call void @_Z4getXv
117  // CHECK: call zeroext i1 @_ZN1XcvbEv
118  // CHECK: call void @_ZN1XD1Ev
119  // CHECK: br
120  while(getX()) { }
121
122  // CHECK: store i32 25
123  z = 25;
124
125  // CHECK: ret
126}
127
128void for_destruct(int z) {
129  // CHECK: define void @_Z12for_destruct
130  // CHECK: call void @_ZN1YC1Ev
131  for(Y y = Y(); X x = X(); ++z)
132    // CHECK: {{for.cond:|:4}}
133    // CHECK: call void @_ZN1XC1Ev
134    // CHECK: {{for.body:|:6}}
135    // CHECK: store i32 23
136    z = 23;
137    // CHECK: {{for.inc:|:7}}
138    // CHECK: br label %{{for.cond.cleanup|10}}
139    // CHECK: {{for.cond.cleanup:|:10}}
140    // CHECK: call void @_ZN1XD1Ev
141  // CHECK: {{for.end:|:12}}
142  // CHECK: call void @_ZN1YD1Ev
143  // CHECK: store i32 24
144  z = 24;
145
146  // CHECK: call void @_Z4getXv
147  // CHECK: call zeroext i1 @_ZN1XcvbEv
148  // CHECK: call void @_ZN1XD1Ev
149  // CHECK: br
150  // CHECK: call void @_Z4getXv
151  // CHECK: load
152  // CHECK: add
153  // CHECK: call void @_ZN1XD1Ev
154  int i = 0;
155  for(; getX(); getX(), ++i) { }
156  z = 26;
157  // CHECK: store i32 26
158  // CHECK: ret
159}
160
161void do_destruct(int z) {
162  // CHECK: define void @_Z11do_destruct
163  do {
164    // CHECK: store i32 77
165    z = 77;
166    // CHECK: call void @_Z4getXv
167    // CHECK: call zeroext i1 @_ZN1XcvbEv
168    // CHECK: call void @_ZN1XD1Ev
169    // CHECK: br
170  } while (getX());
171  // CHECK: store i32 99
172  z = 99;
173  // CHECK: ret
174}
175
176int f(X);
177
178template<typename T>
179int instantiated(T x) {
180  int result;
181
182  // CHECK: call void @_ZN1XC1ERKS_
183  // CHECK: call i32 @_Z1f1X
184  // CHECK: call void @_ZN1XD1Ev
185  // CHECK: br
186  // CHECK: store i32 2
187  // CHECK: br
188  // CHECK: store i32 3
189  if (f(x)) { result = 2; } else { result = 3; }
190
191  // CHECK: call void @_ZN1XC1ERKS_
192  // CHECK: call i32 @_Z1f1X
193  // CHECK: call void @_ZN1XD1Ev
194  // CHECK: br
195  // CHECK: store i32 4
196  // CHECK: br
197  while (f(x)) { result = 4; }
198
199  // CHECK: call void @_ZN1XC1ERKS_
200  // CHECK: call i32 @_Z1f1X
201  // CHECK: call void @_ZN1XD1Ev
202  // CHECK: br
203  // CHECK: store i32 6
204  // CHECK: br
205  // CHECK: call void @_ZN1XC1ERKS_
206  // CHECK: call i32 @_Z1f1X
207  // CHECK: store i32 5
208  // CHECK: call void @_ZN1XD1Ev
209  // CHECK: br
210  for (; f(x); f(x), result = 5) {
211    result = 6;
212  }
213
214  // CHECK: call void @_ZN1XC1ERKS_
215  // CHECK: call i32 @_Z1f1X
216  // CHECK: call void @_ZN1XD1Ev
217  // CHECK: switch i32
218  // CHECK: store i32 7
219  // CHECK: store i32 8
220  switch (f(x)) {
221  case 0:
222    result = 7;
223    break;
224
225  case 1:
226    result = 8;
227  }
228
229  // CHECK: store i32 9
230  // CHECK: br
231  // CHECK: call void @_ZN1XC1ERKS_
232  // CHECK: call i32 @_Z1f1X
233  // CHECK: call void @_ZN1XD1Ev
234  // CHECK: br
235  do {
236    result = 9;
237  } while (f(x));
238
239  // CHECK: store i32 10
240  // CHECK: call void @_ZN1XC1ERKS_
241  // CHECK: call zeroext i1 @_ZN1XcvbEv
242  // CHECK: call void @_ZN1XD1Ev
243  // CHECK: br
244  do {
245    result = 10;
246  } while (X(x));
247
248  // CHECK: ret i32
249  return result;
250}
251
252template int instantiated(X);
253