1 | // RUN: %clang_analyze_cc1 -std=c++98 -fcxx-exceptions -fexceptions -analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=false %s > %t 2>&1 |
2 | // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX98,WARNINGS,CXX98-WARNINGS %s |
3 | // RUN: %clang_analyze_cc1 -std=c++98 -fcxx-exceptions -fexceptions -analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=true %s > %t 2>&1 |
4 | // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX98,ANALYZER,CXX98-ANALYZER %s |
5 | // RUN: %clang_analyze_cc1 -std=c++11 -fcxx-exceptions -fexceptions -analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=false %s > %t 2>&1 |
6 | // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,WARNINGS,CXX11-WARNINGS %s |
7 | // RUN: %clang_analyze_cc1 -std=c++11 -fcxx-exceptions -fexceptions -analyzer-checker=debug.DumpCFG -analyzer-config cfg-rich-constructors=true %s > %t 2>&1 |
8 | // RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,ANALYZER,CXX11-ANALYZER %s |
9 | |
10 | // This file tests how we construct two different flavors of the Clang CFG - |
11 | // the CFG used by the Sema analysis-based warnings and the CFG used by the |
12 | // static analyzer. The difference in the behavior is checked via FileCheck |
13 | // prefixes (WARNINGS and ANALYZER respectively). When introducing new analyzer |
14 | // flags, no new run lines should be added - just these flags would go to the |
15 | // respective line depending on where is it turned on and where is it turned |
16 | // off. Feel free to add tests that test only one of the CFG flavors if you're |
17 | // not sure how the other flavor is supposed to work in your case. |
18 | |
19 | class A { |
20 | public: |
21 | int x; |
22 | |
23 | // CHECK: [B1 (ENTRY)] |
24 | // CHECK-NEXT: Succs (1): B0 |
25 | // CHECK: [B0 (EXIT)] |
26 | // CHECK-NEXT: Preds (1): B1 |
27 | A() {} |
28 | |
29 | // CHECK: [B1 (ENTRY)] |
30 | // CHECK-NEXT: Succs (1): B0 |
31 | // CHECK: [B0 (EXIT)] |
32 | // CHECK-NEXT: Preds (1): B1 |
33 | ~A() {} |
34 | |
35 | // CHECK: [B2 (ENTRY)] |
36 | // CHECK-NEXT: Succs (1): B1 |
37 | // CHECK: [B1] |
38 | // CHECK-NEXT: 1: 1 |
39 | // CHECK-NEXT: 2: return [B1.1]; |
40 | // CHECK-NEXT: Preds (1): B2 |
41 | // CHECK-NEXT: Succs (1): B0 |
42 | // CHECK: [B0 (EXIT)] |
43 | // CHECK-NEXT: Preds (1): B1 |
44 | operator int() const { return 1; } |
45 | }; |
46 | |
47 | extern const bool UV; |
48 | |
49 | // CHECK: [B2 (ENTRY)] |
50 | // CHECK-NEXT: Succs (1): B1 |
51 | // CHECK: [B1] |
52 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
53 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
54 | // CHECK-NEXT: 2: A a; |
55 | // CHECK-NEXT: 3: a |
56 | // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class A) |
57 | // CHECK-NEXT: 5: const A &b = a; |
58 | // WARNINGS-NEXT: 6: A() (CXXConstructExpr, class A) |
59 | // ANALYZER-NEXT: 6: A() (CXXConstructExpr, [B1.9], class A) |
60 | // CHECK-NEXT: 7: [B1.6] (BindTemporary) |
61 | // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) |
62 | // CHECK-NEXT: 9: [B1.8] |
63 | // CHECK: 10: const A &c = A(); |
64 | // CHECK: 11: [B1.10].~A() (Implicit destructor) |
65 | // CHECK: 12: [B1.2].~A() (Implicit destructor) |
66 | // CHECK-NEXT: Preds (1): B2 |
67 | // CHECK-NEXT: Succs (1): B0 |
68 | // CHECK: [B0 (EXIT)] |
69 | // CHECK-NEXT: Preds (1): B1 |
70 | void test_const_ref() { |
71 | A a; |
72 | const A& b = a; |
73 | const A& c = A(); |
74 | } |
75 | |
76 | // CHECK: [B2 (ENTRY)] |
77 | // CHECK-NEXT: Succs (1): B1 |
78 | // CHECK: [B1] |
79 | // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) |
80 | // CXX98-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], class A) |
81 | // CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.3], class A) |
82 | // CHECK-NEXT: 2: [B1.1] (BindTemporary) |
83 | // CXX98-NEXT: 3: [B1.2].x |
84 | // CXX98-NEXT: 4: [B1.3] |
85 | // CXX98-NEXT: 5: const int &x = A().x; |
86 | // CXX98-NEXT: 6: [B1.5].~A() (Implicit destructor) |
87 | // CXX11-NEXT: 3: [B1.2] |
88 | // CXX11-NEXT: 4: [B1.3].x |
89 | // CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const int) |
90 | // CXX11-NEXT: 6: const int &x = A().x; |
91 | // CXX11-NEXT: 7: [B1.6].~A() (Implicit destructor) |
92 | // CHECK-NEXT: Preds (1): B2 |
93 | // CHECK-NEXT: Succs (1): B0 |
94 | // CHECK: [B0 (EXIT)] |
95 | // CHECK-NEXT: Preds (1): B1 |
96 | void test_const_ref_to_field() { |
97 | const int &x = A().x; |
98 | } |
99 | |
100 | // CHECK: [B2 (ENTRY)] |
101 | // CHECK-NEXT: Succs (1): B1 |
102 | // CHECK: [B1] |
103 | // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) |
104 | // CXX98-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], class A) |
105 | // CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.3], class A) |
106 | // CHECK-NEXT: 2: [B1.1] (BindTemporary) |
107 | // CXX98-NEXT: 3: A::x |
108 | // CXX98-NEXT: 4: &[B1.3] |
109 | // CXX98-NEXT: 5: [B1.2] .* [B1.4] |
110 | // CXX98-NEXT: 6: [B1.5] |
111 | // CXX98-NEXT: 7: const int &x = A() .* &A::x; |
112 | // CXX98-NEXT: 8: [B1.7].~A() (Implicit destructor) |
113 | // CXX11-NEXT: 3: [B1.2] |
114 | // CXX11-NEXT: 4: A::x |
115 | // CXX11-NEXT: 5: &[B1.4] |
116 | // CXX11-NEXT: 6: [B1.3] .* [B1.5] |
117 | // CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, NoOp, const int) |
118 | // CXX11-NEXT: 8: const int &x = A() .* &A::x; |
119 | // CXX11-NEXT: 9: [B1.8].~A() (Implicit destructor) |
120 | // CHECK-NEXT: Preds (1): B2 |
121 | // CHECK-NEXT: Succs (1): B0 |
122 | // CHECK: [B0 (EXIT)] |
123 | // CHECK-NEXT: Preds (1): B1 |
124 | void test_pointer_to_member() { |
125 | const int &x = A().*&A::x; |
126 | } |
127 | |
128 | // FIXME: There should be automatic destructors at the end of scope. |
129 | // CHECK: [B2 (ENTRY)] |
130 | // CHECK-NEXT: Succs (1): B1 |
131 | // CHECK: [B1] |
132 | // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) |
133 | // ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.4], class A) |
134 | // CHECK-NEXT: 2: [B1.1] (BindTemporary) |
135 | // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) |
136 | // CHECK-NEXT: 4: [B1.3] |
137 | // CHECK-NEXT: 5: {[B1.4]} |
138 | // CHECK-NEXT: 6: B b = {A()}; |
139 | // WARNINGS-NEXT: 7: A() (CXXConstructExpr, class A) |
140 | // ANALYZER-NEXT: 7: A() (CXXConstructExpr, [B1.10], class A) |
141 | // CHECK-NEXT: 8: [B1.7] (BindTemporary) |
142 | // CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class A) |
143 | // CHECK-NEXT: 10: [B1.9] |
144 | // CHECK-NEXT: 11: {[B1.10]} |
145 | // WARNINGS-NEXT: 12: A() (CXXConstructExpr, class A) |
146 | // ANALYZER-NEXT: 12: A() (CXXConstructExpr, [B1.15], class A) |
147 | // CHECK-NEXT: 13: [B1.12] (BindTemporary) |
148 | // CHECK-NEXT: 14: [B1.13] (ImplicitCastExpr, NoOp, const class A) |
149 | // CHECK-NEXT: 15: [B1.14] |
150 | // CHECK-NEXT: 16: {[B1.15]} |
151 | // CHECK-NEXT: 17: {[B1.10], [B1.15]} |
152 | // CHECK-NEXT: 18: B bb[2] = {A(), A()}; |
153 | // CHECK-NEXT: Preds (1): B2 |
154 | // CHECK-NEXT: Succs (1): B0 |
155 | // CHECK: [B0 (EXIT)] |
156 | // CHECK-NEXT: Preds (1): B1 |
157 | void test_aggregate_lifetime_extension() { |
158 | struct B { |
159 | const A &x; |
160 | }; |
161 | |
162 | B b = {A()}; |
163 | B bb[2] = {A(), A()}; |
164 | } |
165 | |
166 | // In C++98 such class 'C' will not be an aggregate. |
167 | #if __cplusplus >= 201103L |
168 | // FIXME: There should be automatic destructors at the end of the scope. |
169 | // CXX11: [B2 (ENTRY)] |
170 | // CXX11-NEXT: Succs (1): B1 |
171 | // CXX11: [B1] |
172 | // CXX11-WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) |
173 | // CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A) |
174 | // CXX11-NEXT: 2: [B1.1] (BindTemporary) |
175 | // CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) |
176 | // CXX11-NEXT: 4: [B1.3] |
177 | // CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, const class A) |
178 | // CXX11-WARNINGS-NEXT: 6: A() (CXXConstructExpr, class A) |
179 | // CXX11-ANALYZER-NEXT: 6: A() (CXXConstructExpr, [B1.7], [B1.9], class A) |
180 | // CXX11-NEXT: 7: [B1.6] (BindTemporary) |
181 | // CXX11-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) |
182 | // CXX11-NEXT: 9: [B1.8] |
183 | // CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, const class A) |
184 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
185 | // CXX11-NEXT: 11: {[B1.2], [B1.7]} |
186 | // CXX11-NEXT: 12: [B1.11] (BindTemporary) |
187 | // CXX11-NEXT: 13: [B1.12] |
188 | // CXX11-NEXT: 14: {[B1.13]} |
189 | // Double curly braces trigger regexps, escape as per FileCheck manual. |
190 | // CXX11-NEXT: 15: C c = {{[{][{]}}A(), A(){{[}][}]}}; |
191 | // CXX11-NEXT: 16: ~A() (Temporary object destructor) |
192 | // CXX11-NEXT: 17: ~A() (Temporary object destructor) |
193 | // CXX11-WARNINGS-NEXT: 18: A() (CXXConstructExpr, class A) |
194 | // CXX11-ANALYZER-NEXT: 18: A() (CXXConstructExpr, [B1.19], [B1.21], class A) |
195 | // CXX11-NEXT: 19: [B1.18] (BindTemporary) |
196 | // CXX11-NEXT: 20: [B1.19] (ImplicitCastExpr, NoOp, const class A) |
197 | // CXX11-NEXT: 21: [B1.20] |
198 | // CXX11-NEXT: 22: [B1.21] (CXXConstructExpr, const class A) |
199 | // CXX11-WARNINGS-NEXT: 23: A() (CXXConstructExpr, class A) |
200 | // CXX11-ANALYZER-NEXT: 23: A() (CXXConstructExpr, [B1.24], [B1.26], class A) |
201 | // CXX11-NEXT: 24: [B1.23] (BindTemporary) |
202 | // CXX11-NEXT: 25: [B1.24] (ImplicitCastExpr, NoOp, const class A) |
203 | // CXX11-NEXT: 26: [B1.25] |
204 | // CXX11-NEXT: 27: [B1.26] (CXXConstructExpr, const class A) |
205 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
206 | // CXX11-NEXT: 28: {[B1.19], [B1.24]} |
207 | // CXX11-NEXT: 29: [B1.28] (BindTemporary) |
208 | // CXX11-NEXT: 30: [B1.29] |
209 | // CXX11-NEXT: 31: {[B1.30]} |
210 | // CXX11-WARNINGS-NEXT: 32: A() (CXXConstructExpr, class A) |
211 | // CXX11-ANALYZER-NEXT: 32: A() (CXXConstructExpr, [B1.33], [B1.35], class A) |
212 | // CXX11-NEXT: 33: [B1.32] (BindTemporary) |
213 | // CXX11-NEXT: 34: [B1.33] (ImplicitCastExpr, NoOp, const class A) |
214 | // CXX11-NEXT: 35: [B1.34] |
215 | // CXX11-NEXT: 36: [B1.35] (CXXConstructExpr, const class A) |
216 | // CXX11-WARNINGS-NEXT: 37: A() (CXXConstructExpr, class A) |
217 | // CXX11-ANALYZER-NEXT: 37: A() (CXXConstructExpr, [B1.38], [B1.40], class A) |
218 | // CXX11-NEXT: 38: [B1.37] (BindTemporary) |
219 | // CXX11-NEXT: 39: [B1.38] (ImplicitCastExpr, NoOp, const class A) |
220 | // CXX11-NEXT: 40: [B1.39] |
221 | // CXX11-NEXT: 41: [B1.40] (CXXConstructExpr, const class A) |
222 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
223 | // CXX11-NEXT: 42: {[B1.33], [B1.38]} |
224 | // CXX11-NEXT: 43: [B1.42] (BindTemporary) |
225 | // CXX11-NEXT: 44: [B1.43] |
226 | // CXX11-NEXT: 45: {[B1.44]} |
227 | // Double curly braces trigger regexps, escape as per FileCheck manual. |
228 | // CXX11-NEXT: 46: {{[{][{]}}[B1.30]}, {[B1.44]{{[}][}]}} |
229 | // Double curly braces trigger regexps, escape as per FileCheck manual. |
230 | // CXX11-NEXT: 47: C cc[2] = {{[{][{][{]}}A(), A(){{[}][}]}}, {{[{][{]}}A(), A(){{[}][}][}]}}; |
231 | // CXX11-NEXT: 48: ~A() (Temporary object destructor) |
232 | // CXX11-NEXT: 49: ~A() (Temporary object destructor) |
233 | // CXX11-NEXT: 50: ~A() (Temporary object destructor) |
234 | // CXX11-NEXT: 51: ~A() (Temporary object destructor) |
235 | // CXX11-NEXT: Preds (1): B2 |
236 | // CXX11-NEXT: Succs (1): B0 |
237 | // CXX11: [B0 (EXIT)] |
238 | // CXX11-NEXT: Preds (1): B1 |
239 | void test_aggregate_array_lifetime_extension() { |
240 | struct C { |
241 | const A (&z)[2]; |
242 | }; |
243 | |
244 | // Until C++17 there are elidable copies here, so there should be 9 temporary |
245 | // destructors of A()s. There are no destructors of 'c' and 'cc' because this |
246 | // aggregate has no destructor. Instead, arrays are lifetime-extended, |
247 | // and copies of A()s within them need to be destroyed via automatic |
248 | // destructors. |
249 | C c = {{A(), A()}}; |
250 | C cc[2] = {{{A(), A()}}, {{A(), A()}}}; |
251 | } |
252 | #endif |
253 | |
254 | // CHECK: [B2 (ENTRY)] |
255 | // CHECK-NEXT: Succs (1): B1 |
256 | // CHECK: [B1] |
257 | // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) |
258 | // ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A) |
259 | // CHECK-NEXT: 2: [B1.1] (BindTemporary) |
260 | // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) |
261 | // CHECK-NEXT: 4: [B1.3] |
262 | // CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, class A) |
263 | // WARNINGS-NEXT: 6: A() (CXXConstructExpr, class A) |
264 | // ANALYZER-NEXT: 6: A() (CXXConstructExpr, [B1.7], [B1.9], class A) |
265 | // CHECK-NEXT: 7: [B1.6] (BindTemporary) |
266 | // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) |
267 | // CHECK-NEXT: 9: [B1.8] |
268 | // CHECK-NEXT: 10: [B1.9] (CXXConstructExpr, class A) |
269 | // WARNINGS-NEXT: 11: A() (CXXConstructExpr, class A) |
270 | // ANALYZER-NEXT: 11: A() (CXXConstructExpr, [B1.12], [B1.14], class A) |
271 | // CHECK-NEXT: 12: [B1.11] (BindTemporary) |
272 | // CHECK-NEXT: 13: [B1.12] (ImplicitCastExpr, NoOp, const class A) |
273 | // CHECK-NEXT: 14: [B1.13] |
274 | // CHECK-NEXT: 15: [B1.14] (CXXConstructExpr, class A) |
275 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
276 | // CHECK-NEXT: 16: {[B1.7], [B1.12]} |
277 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
278 | // CHECK-NEXT: 17: {[B1.2], {[B1.7], [B1.12]}} |
279 | // CHECK-NEXT: 18: D d = {A(), {A(), A()}}; |
280 | // CHECK-NEXT: 19: ~A() (Temporary object destructor) |
281 | // CHECK-NEXT: 20: ~A() (Temporary object destructor) |
282 | // CHECK-NEXT: 21: ~A() (Temporary object destructor) |
283 | // WARNINGS-NEXT: 22: A() (CXXConstructExpr, class A) |
284 | // ANALYZER-NEXT: 22: A() (CXXConstructExpr, [B1.23], [B1.25], class A) |
285 | // CHECK-NEXT: 23: [B1.22] (BindTemporary) |
286 | // CHECK-NEXT: 24: [B1.23] (ImplicitCastExpr, NoOp, const class A) |
287 | // CHECK-NEXT: 25: [B1.24] |
288 | // CHECK-NEXT: 26: [B1.25] (CXXConstructExpr, class A) |
289 | // WARNINGS-NEXT: 27: A() (CXXConstructExpr, class A) |
290 | // ANALYZER-NEXT: 27: A() (CXXConstructExpr, [B1.28], [B1.30], class A) |
291 | // CHECK-NEXT: 28: [B1.27] (BindTemporary) |
292 | // CHECK-NEXT: 29: [B1.28] (ImplicitCastExpr, NoOp, const class A) |
293 | // CHECK-NEXT: 30: [B1.29] |
294 | // CHECK-NEXT: 31: [B1.30] (CXXConstructExpr, class A) |
295 | // WARNINGS-NEXT: 32: A() (CXXConstructExpr, class A) |
296 | // ANALYZER-NEXT: 32: A() (CXXConstructExpr, [B1.33], [B1.35], class A) |
297 | // CHECK-NEXT: 33: [B1.32] (BindTemporary) |
298 | // CHECK-NEXT: 34: [B1.33] (ImplicitCastExpr, NoOp, const class A) |
299 | // CHECK-NEXT: 35: [B1.34] |
300 | // CHECK-NEXT: 36: [B1.35] (CXXConstructExpr, class A) |
301 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
302 | // CHECK-NEXT: 37: {[B1.28], [B1.33]} |
303 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
304 | // CHECK-NEXT: 38: {[B1.23], {[B1.28], [B1.33]}} |
305 | // WARNINGS-NEXT: 39: A() (CXXConstructExpr, class A) |
306 | // ANALYZER-NEXT: 39: A() (CXXConstructExpr, [B1.40], [B1.42], class A) |
307 | // CHECK-NEXT: 40: [B1.39] (BindTemporary) |
308 | // CHECK-NEXT: 41: [B1.40] (ImplicitCastExpr, NoOp, const class A) |
309 | // CHECK-NEXT: 42: [B1.41] |
310 | // CHECK-NEXT: 43: [B1.42] (CXXConstructExpr, class A) |
311 | // WARNINGS-NEXT: 44: A() (CXXConstructExpr, class A) |
312 | // ANALYZER-NEXT: 44: A() (CXXConstructExpr, [B1.45], [B1.47], class A) |
313 | // CHECK-NEXT: 45: [B1.44] (BindTemporary) |
314 | // CHECK-NEXT: 46: [B1.45] (ImplicitCastExpr, NoOp, const class A) |
315 | // CHECK-NEXT: 47: [B1.46] |
316 | // CHECK-NEXT: 48: [B1.47] (CXXConstructExpr, class A) |
317 | // WARNINGS-NEXT: 49: A() (CXXConstructExpr, class A) |
318 | // ANALYZER-NEXT: 49: A() (CXXConstructExpr, [B1.50], [B1.52], class A) |
319 | // CHECK-NEXT: 50: [B1.49] (BindTemporary) |
320 | // CHECK-NEXT: 51: [B1.50] (ImplicitCastExpr, NoOp, const class A) |
321 | // CHECK-NEXT: 52: [B1.51] |
322 | // CHECK-NEXT: 53: [B1.52] (CXXConstructExpr, class A) |
323 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
324 | // CHECK-NEXT: 54: {[B1.45], [B1.50]} |
325 | // FIXME: Why does it look as if the initializer list consumes uncopied objects? |
326 | // CHECK-NEXT: 55: {[B1.40], {[B1.45], [B1.50]}} |
327 | // Double curly braces trigger regexps, escape as per FileCheck manual. |
328 | // CHECK-NEXT: 56: {{[{][{]}}[B1.23], {[B1.28], [B1.33]{{[}][}]}}, {[B1.40], {[B1.45], [B1.50]{{[}][}][}]}} |
329 | // Double curly braces trigger regexps, escape as per FileCheck manual. |
330 | // CHECK-NEXT: 57: D dd[2] = {{[{][{]}}A(), {A(), A(){{[}][}]}}, {A(), {A(), A(){{[}][}][}]}}; |
331 | // CHECK-NEXT: 58: ~A() (Temporary object destructor) |
332 | // CHECK-NEXT: 59: ~A() (Temporary object destructor) |
333 | // CHECK-NEXT: 60: ~A() (Temporary object destructor) |
334 | // CHECK-NEXT: 61: ~A() (Temporary object destructor) |
335 | // CHECK-NEXT: 62: ~A() (Temporary object destructor) |
336 | // CHECK-NEXT: 63: ~A() (Temporary object destructor) |
337 | // CHECK-NEXT: 64: [B1.57].~D() (Implicit destructor) |
338 | // CHECK-NEXT: 65: [B1.18].~D() (Implicit destructor) |
339 | // CHECK-NEXT: Preds (1): B2 |
340 | // CHECK-NEXT: Succs (1): B0 |
341 | // CHECK: [B0 (EXIT)] |
342 | // CHECK-NEXT: Preds (1): B1 |
343 | void test_aggregate_with_nontrivial_own_destructor() { |
344 | struct D { |
345 | A y; |
346 | A w[2]; |
347 | }; |
348 | |
349 | // Until C++17 there are elidable copies here, so there should be 9 temporary |
350 | // destructors of A()s. Destructors of 'd' and 'dd' should implicitly |
351 | // take care of the copies, so there should not be automatic destructors |
352 | // for copies of A()s. |
353 | D d = {A(), {A(), A()}}; |
354 | D dd[2] = {{A(), {A(), A()}}, {A(), {A(), A()}}}; |
355 | } |
356 | |
357 | // CHECK: [B2 (ENTRY)] |
358 | // CHECK-NEXT: Succs (1): B1 |
359 | // CHECK: [B1] |
360 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A [2]) |
361 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], class A [2]) |
362 | // CHECK-NEXT: 2: A a[2]; |
363 | // WARNINGS-NEXT: 3: (CXXConstructExpr, class A [0]) |
364 | // ANALYZER-NEXT: 3: (CXXConstructExpr, [B1.4], class A [0]) |
365 | // CHECK-NEXT: 4: A b[0]; |
366 | // CHECK-NEXT: 5: [B1.2].~A() (Implicit destructor) |
367 | // CHECK-NEXT: Preds (1): B2 |
368 | // CHECK-NEXT: Succs (1): B0 |
369 | // CHECK: [B0 (EXIT)] |
370 | // CHECK-NEXT: Preds (1): B1 |
371 | void test_array() { |
372 | A a[2]; |
373 | A b[0]; |
374 | } |
375 | |
376 | // CHECK: [B2 (ENTRY)] |
377 | // CHECK-NEXT: Succs (1): B1 |
378 | // CHECK: [B1] |
379 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
380 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
381 | // CHECK-NEXT: 2: A a; |
382 | // WARNINGS-NEXT: 3: (CXXConstructExpr, class A) |
383 | // ANALYZER-NEXT: 3: (CXXConstructExpr, [B1.4], class A) |
384 | // CHECK-NEXT: 4: A c; |
385 | // WARNINGS-NEXT: 5: (CXXConstructExpr, class A) |
386 | // ANALYZER-NEXT: 5: (CXXConstructExpr, [B1.6], class A) |
387 | // CHECK-NEXT: 6: A d; |
388 | // CHECK-NEXT: 7: [B1.6].~A() (Implicit destructor) |
389 | // CHECK-NEXT: 8: [B1.4].~A() (Implicit destructor) |
390 | // WARNINGS-NEXT: 9: (CXXConstructExpr, class A) |
391 | // ANALYZER-NEXT: 9: (CXXConstructExpr, [B1.10], class A) |
392 | // CHECK: 10: A b; |
393 | // CHECK: 11: [B1.10].~A() (Implicit destructor) |
394 | // CHECK: 12: [B1.2].~A() (Implicit destructor) |
395 | // CHECK-NEXT: Preds (1): B2 |
396 | // CHECK-NEXT: Succs (1): B0 |
397 | // CHECK: [B0 (EXIT)] |
398 | // CHECK-NEXT: Preds (1): B1 |
399 | void test_scope() { |
400 | A a; |
401 | { A c; |
402 | A d; |
403 | } |
404 | A b; |
405 | } |
406 | |
407 | // CHECK: [B4 (ENTRY)] |
408 | // CHECK-NEXT: Succs (1): B3 |
409 | // CHECK: [B1] |
410 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
411 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
412 | // CHECK-NEXT: 2: A c; |
413 | // CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) |
414 | // CHECK-NEXT: 4: [B3.4].~A() (Implicit destructor) |
415 | // CHECK-NEXT: 5: [B3.2].~A() (Implicit destructor) |
416 | // CHECK-NEXT: Preds (1): B3 |
417 | // CHECK-NEXT: Succs (1): B0 |
418 | // CHECK: [B2] |
419 | // CHECK-NEXT: 1: return; |
420 | // CHECK-NEXT: 2: [B3.4].~A() (Implicit destructor) |
421 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
422 | // CHECK-NEXT: Preds (1): B3 |
423 | // CHECK-NEXT: Succs (1): B0 |
424 | // CHECK: [B3] |
425 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
426 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
427 | // CHECK-NEXT: 2: A a; |
428 | // WARNINGS-NEXT: 3: (CXXConstructExpr, class A) |
429 | // ANALYZER-NEXT: 3: (CXXConstructExpr, [B3.4], class A) |
430 | // CHECK-NEXT: 4: A b; |
431 | // CHECK-NEXT: 5: UV |
432 | // CHECK-NEXT: 6: [B3.5] (ImplicitCastExpr, LValueToRValue, _Bool) |
433 | // CHECK-NEXT: T: if [B3.6] |
434 | // CHECK-NEXT: Preds (1): B4 |
435 | // CHECK-NEXT: Succs (2): B2 B1 |
436 | // CHECK: [B0 (EXIT)] |
437 | // CHECK-NEXT: Preds (2): B1 B2 |
438 | void test_return() { |
439 | A a; |
440 | A b; |
441 | if (UV) return; |
442 | A c; |
443 | } |
444 | |
445 | // CHECK: [B8 (ENTRY)] |
446 | // CHECK-NEXT: Succs (1): B7 |
447 | // CHECK: [B1] |
448 | // CHECK: l1: |
449 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
450 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
451 | // CHECK-NEXT: 2: A c; |
452 | // CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) |
453 | // CHECK-NEXT: 4: [B6.2].~A() (Implicit destructor) |
454 | // CHECK-NEXT: 5: [B7.2].~A() (Implicit destructor) |
455 | // CHECK-NEXT: Preds (2): B2 B3 |
456 | // CHECK-NEXT: Succs (1): B0 |
457 | // CHECK: [B2] |
458 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
459 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
460 | // CHECK-NEXT: 2: A b; |
461 | // CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) |
462 | // CHECK-NEXT: 4: [B6.4].~A() (Implicit destructor) |
463 | // CHECK-NEXT: Preds (1): B4 |
464 | // CHECK-NEXT: Succs (1): B1 |
465 | // CHECK: [B3] |
466 | // CHECK-NEXT: 1: [B6.4].~A() (Implicit destructor) |
467 | // CHECK-NEXT: T: goto l1; |
468 | // CHECK: Preds (1): B4 |
469 | // CHECK-NEXT: Succs (1): B1 |
470 | // CHECK: [B4] |
471 | // CHECK-NEXT: 1: UV |
472 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
473 | // CHECK-NEXT: T: if [B4.2] |
474 | // CHECK-NEXT: Preds (1): B6 |
475 | // CHECK-NEXT: Succs (2): B3 B2 |
476 | // CHECK: [B5] |
477 | // CHECK-NEXT: 1: [B6.4].~A() (Implicit destructor) |
478 | // CHECK-NEXT: 2: [B6.2].~A() (Implicit destructor) |
479 | // CHECK-NEXT: T: goto l0; |
480 | // CHECK: Preds (1): B6 |
481 | // CHECK-NEXT: Succs (1): B6 |
482 | // CHECK: [B6] |
483 | // CHECK: l0: |
484 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
485 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B6.2], class A) |
486 | // CHECK-NEXT: 2: A b; |
487 | // WARNINGS-NEXT: 3: (CXXConstructExpr, class A) |
488 | // ANALYZER-NEXT: 3: (CXXConstructExpr, [B6.4], class A) |
489 | // CHECK-NEXT: 4: A a; |
490 | // CHECK-NEXT: 5: UV |
491 | // CHECK-NEXT: 6: [B6.5] (ImplicitCastExpr, LValueToRValue, _Bool) |
492 | // CHECK-NEXT: T: if [B6.6] |
493 | // CHECK-NEXT: Preds (2): B7 B5 |
494 | // CHECK-NEXT: Succs (2): B5 B4 |
495 | // CHECK: [B7] |
496 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
497 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B7.2], class A) |
498 | // CHECK-NEXT: 2: A a; |
499 | // CHECK-NEXT: Preds (1): B8 |
500 | // CHECK-NEXT: Succs (1): B6 |
501 | // CHECK: [B0 (EXIT)] |
502 | // CHECK-NEXT: Preds (1): B1 |
503 | void test_goto() { |
504 | A a; |
505 | l0: |
506 | A b; |
507 | { A a; |
508 | if (UV) goto l0; |
509 | if (UV) goto l1; |
510 | A b; |
511 | } |
512 | l1: |
513 | A c; |
514 | } |
515 | |
516 | // CHECK: [B5 (ENTRY)] |
517 | // CHECK-NEXT: Succs (1): B4 |
518 | // CHECK: [B1] |
519 | // CHECK-NEXT: 1: [B4.6].~A() (Implicit destructor) |
520 | // CHECK-NEXT: 2: [B4.2].~A() (Implicit destructor) |
521 | // CHECK-NEXT: Preds (2): B2 B3 |
522 | // CHECK-NEXT: Succs (1): B0 |
523 | // CHECK: [B2] |
524 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
525 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
526 | // CHECK-NEXT: 2: A c; |
527 | // CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) |
528 | // CHECK-NEXT: Preds (1): B4 |
529 | // CHECK-NEXT: Succs (1): B1 |
530 | // CHECK: [B3] |
531 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
532 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
533 | // CHECK-NEXT: 2: A c; |
534 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
535 | // CHECK-NEXT: Preds (1): B4 |
536 | // CHECK-NEXT: Succs (1): B1 |
537 | // CHECK: [B4] |
538 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
539 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B4.2], class A) |
540 | // CHECK-NEXT: 2: A a; |
541 | // CHECK-NEXT: 3: a |
542 | // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, NoOp, const class A) |
543 | // WARNINGS-NEXT: 5: [B4.4] (CXXConstructExpr, class A) |
544 | // ANALYZER-NEXT: 5: [B4.4] (CXXConstructExpr, [B4.6], class A) |
545 | // CHECK-NEXT: 6: A b = a; |
546 | // CHECK-NEXT: 7: b |
547 | // CHECK-NEXT: 8: [B4.7] (ImplicitCastExpr, NoOp, const class A) |
548 | // CHECK-NEXT: 9: [B4.8].operator int |
549 | // CHECK: 10: [B4.8] |
550 | // CHECK: 11: [B4.10] (ImplicitCastExpr, UserDefinedConversion, int) |
551 | // CHECK: 12: [B4.11] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
552 | // CHECK-NEXT: T: if [B4.12] |
553 | // CHECK-NEXT: Preds (1): B5 |
554 | // CHECK-NEXT: Succs (2): B3 B2 |
555 | // CHECK: [B0 (EXIT)] |
556 | // CHECK-NEXT: Preds (1): B1 |
557 | void test_if_implicit_scope() { |
558 | A a; |
559 | if (A b = a) |
560 | A c; |
561 | else A c; |
562 | } |
563 | |
564 | // CHECK: [B9 (ENTRY)] |
565 | // CHECK-NEXT: Succs (1): B8 |
566 | // CHECK: [B1] |
567 | // CHECK-NEXT: 1: [B8.6].~A() (Implicit destructor) |
568 | // WARNINGS-NEXT: 2: (CXXConstructExpr, class A) |
569 | // ANALYZER-NEXT: 2: (CXXConstructExpr, [B1.3], class A) |
570 | // CHECK-NEXT: 3: A e; |
571 | // CHECK-NEXT: 4: [B1.3].~A() (Implicit destructor) |
572 | // CHECK-NEXT: 5: [B8.2].~A() (Implicit destructor) |
573 | // CHECK-NEXT: Preds (2): B2 B5 |
574 | // CHECK-NEXT: Succs (1): B0 |
575 | // CHECK: [B2] |
576 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
577 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
578 | // CHECK-NEXT: 2: A d; |
579 | // CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) |
580 | // CHECK-NEXT: 4: [B4.2].~A() (Implicit destructor) |
581 | // CHECK-NEXT: Preds (1): B4 |
582 | // CHECK-NEXT: Succs (1): B1 |
583 | // CHECK: [B3] |
584 | // CHECK-NEXT: 1: return; |
585 | // CHECK-NEXT: 2: [B4.2].~A() (Implicit destructor) |
586 | // CHECK-NEXT: 3: [B8.6].~A() (Implicit destructor) |
587 | // CHECK-NEXT: 4: [B8.2].~A() (Implicit destructor) |
588 | // CHECK-NEXT: Preds (1): B4 |
589 | // CHECK-NEXT: Succs (1): B0 |
590 | // CHECK: [B4] |
591 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
592 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B4.2], class A) |
593 | // CHECK-NEXT: 2: A c; |
594 | // CHECK-NEXT: 3: UV |
595 | // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
596 | // CHECK-NEXT: T: if [B4.4] |
597 | // CHECK-NEXT: Preds (1): B8 |
598 | // CHECK-NEXT: Succs (2): B3 B2 |
599 | // CHECK: [B5] |
600 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
601 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B5.2], class A) |
602 | // CHECK-NEXT: 2: A d; |
603 | // CHECK-NEXT: 3: [B5.2].~A() (Implicit destructor) |
604 | // CHECK-NEXT: 4: [B7.2].~A() (Implicit destructor) |
605 | // CHECK-NEXT: Preds (1): B7 |
606 | // CHECK-NEXT: Succs (1): B1 |
607 | // CHECK: [B6] |
608 | // CHECK-NEXT: 1: return; |
609 | // CHECK-NEXT: 2: [B7.2].~A() (Implicit destructor) |
610 | // CHECK-NEXT: 3: [B8.6].~A() (Implicit destructor) |
611 | // CHECK-NEXT: 4: [B8.2].~A() (Implicit destructor) |
612 | // CHECK-NEXT: Preds (1): B7 |
613 | // CHECK-NEXT: Succs (1): B0 |
614 | // CHECK: [B7] |
615 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
616 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B7.2], class A) |
617 | // CHECK-NEXT: 2: A c; |
618 | // CHECK-NEXT: 3: UV |
619 | // CHECK-NEXT: 4: [B7.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
620 | // CHECK-NEXT: T: if [B7.4] |
621 | // CHECK-NEXT: Preds (1): B8 |
622 | // CHECK-NEXT: Succs (2): B6 B5 |
623 | // CHECK: [B8] |
624 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
625 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B8.2], class A) |
626 | // CHECK-NEXT: 2: A a; |
627 | // CHECK-NEXT: 3: a |
628 | // CHECK-NEXT: 4: [B8.3] (ImplicitCastExpr, NoOp, const class A) |
629 | // WARNINGS-NEXT: 5: [B8.4] (CXXConstructExpr, class A) |
630 | // ANALYZER-NEXT: 5: [B8.4] (CXXConstructExpr, [B8.6], class A) |
631 | // CHECK-NEXT: 6: A b = a; |
632 | // CHECK-NEXT: 7: b |
633 | // CHECK-NEXT: 8: [B8.7] (ImplicitCastExpr, NoOp, const class A) |
634 | // CHECK-NEXT: 9: [B8.8].operator int |
635 | // CHECK: 10: [B8.8] |
636 | // CHECK: 11: [B8.10] (ImplicitCastExpr, UserDefinedConversion, int) |
637 | // CHECK: 12: [B8.11] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
638 | // CHECK-NEXT: T: if [B8.12] |
639 | // CHECK-NEXT: Preds (1): B9 |
640 | // CHECK-NEXT: Succs (2): B7 B4 |
641 | // CHECK: [B0 (EXIT)] |
642 | // CHECK-NEXT: Preds (3): B1 B3 B6 |
643 | void test_if_jumps() { |
644 | A a; |
645 | if (A b = a) { |
646 | A c; |
647 | if (UV) return; |
648 | A d; |
649 | } else { |
650 | A c; |
651 | if (UV) return; |
652 | A d; |
653 | } |
654 | A e; |
655 | } |
656 | |
657 | // CHECK: [B6 (ENTRY)] |
658 | // CHECK-NEXT: Succs (1): B5 |
659 | // CHECK: [B1] |
660 | // CHECK-NEXT: 1: [B4.4].~A() (Implicit destructor) |
661 | // CHECK-NEXT: 2: [B5.2].~A() (Implicit destructor) |
662 | // CHECK-NEXT: Preds (1): B4 |
663 | // CHECK-NEXT: Succs (1): B0 |
664 | // CHECK: [B2] |
665 | // CHECK-NEXT: Preds (1): B3 |
666 | // CHECK-NEXT: Succs (1): B4 |
667 | // CHECK: [B3] |
668 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
669 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
670 | // CHECK-NEXT: 2: A c; |
671 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
672 | // CHECK-NEXT: 4: [B4.4].~A() (Implicit destructor) |
673 | // CHECK-NEXT: Preds (1): B4 |
674 | // CHECK-NEXT: Succs (1): B2 |
675 | // CHECK: [B4] |
676 | // CHECK-NEXT: 1: a |
677 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) |
678 | // WARNINGS-NEXT: 3: [B4.2] (CXXConstructExpr, class A) |
679 | // ANALYZER-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], class A) |
680 | // CHECK-NEXT: 4: A b = a; |
681 | // CHECK-NEXT: 5: b |
682 | // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) |
683 | // CHECK-NEXT: 7: [B4.6].operator int |
684 | // CHECK-NEXT: 8: [B4.6] |
685 | // CHECK-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) |
686 | // CHECK: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
687 | // CHECK-NEXT: T: while [B4.10] |
688 | // CHECK-NEXT: Preds (2): B2 B5 |
689 | // CHECK-NEXT: Succs (2): B3 B1 |
690 | // CHECK: [B5] |
691 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
692 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B5.2], class A) |
693 | // CHECK-NEXT: 2: A a; |
694 | // CHECK-NEXT: Preds (1): B6 |
695 | // CHECK-NEXT: Succs (1): B4 |
696 | // CHECK: [B0 (EXIT)] |
697 | // CHECK-NEXT: Preds (1): B1 |
698 | void test_while_implicit_scope() { |
699 | A a; |
700 | while (A b = a) |
701 | A c; |
702 | } |
703 | |
704 | // CHECK: [B12 (ENTRY)] |
705 | // CHECK-NEXT: Succs (1): B11 |
706 | // CHECK: [B1] |
707 | // CHECK-NEXT: 1: [B10.4].~A() (Implicit destructor) |
708 | // WARNINGS-NEXT: 2: (CXXConstructExpr, class A) |
709 | // ANALYZER-NEXT: 2: (CXXConstructExpr, [B1.3], class A) |
710 | // CHECK-NEXT: 3: A e; |
711 | // CHECK-NEXT: 4: [B1.3].~A() (Implicit destructor) |
712 | // CHECK-NEXT: 5: [B11.2].~A() (Implicit destructor) |
713 | // CHECK-NEXT: Preds (2): B8 B10 |
714 | // CHECK-NEXT: Succs (1): B0 |
715 | // CHECK: [B2] |
716 | // CHECK-NEXT: Preds (2): B3 B6 |
717 | // CHECK-NEXT: Succs (1): B10 |
718 | // CHECK: [B3] |
719 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
720 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
721 | // CHECK-NEXT: 2: A d; |
722 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
723 | // CHECK-NEXT: 4: [B9.2].~A() (Implicit destructor) |
724 | // CHECK-NEXT: 5: [B10.4].~A() (Implicit destructor) |
725 | // CHECK-NEXT: Preds (1): B5 |
726 | // CHECK-NEXT: Succs (1): B2 |
727 | // CHECK: [B4] |
728 | // CHECK-NEXT: 1: return; |
729 | // CHECK-NEXT: 2: [B9.2].~A() (Implicit destructor) |
730 | // CHECK-NEXT: 3: [B10.4].~A() (Implicit destructor) |
731 | // CHECK-NEXT: 4: [B11.2].~A() (Implicit destructor) |
732 | // CHECK-NEXT: Preds (1): B5 |
733 | // CHECK-NEXT: Succs (1): B0 |
734 | // CHECK: [B5] |
735 | // CHECK-NEXT: 1: UV |
736 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
737 | // CHECK-NEXT: T: if [B5.2] |
738 | // CHECK-NEXT: Preds (1): B7 |
739 | // CHECK-NEXT: Succs (2): B4 B3 |
740 | // CHECK: [B6] |
741 | // CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) |
742 | // CHECK-NEXT: 2: [B10.4].~A() (Implicit destructor) |
743 | // CHECK-NEXT: T: continue; |
744 | // CHECK: Preds (1): B7 |
745 | // CHECK-NEXT: Succs (1): B2 |
746 | // CHECK: [B7] |
747 | // CHECK-NEXT: 1: UV |
748 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
749 | // CHECK-NEXT: T: if [B7.2] |
750 | // CHECK-NEXT: Preds (1): B9 |
751 | // CHECK-NEXT: Succs (2): B6 B5 |
752 | // CHECK: [B8] |
753 | // CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) |
754 | // CHECK-NEXT: T: break; |
755 | // CHECK: Preds (1): B9 |
756 | // CHECK-NEXT: Succs (1): B1 |
757 | // CHECK: [B9] |
758 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
759 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B9.2], class A) |
760 | // CHECK-NEXT: 2: A c; |
761 | // CHECK-NEXT: 3: UV |
762 | // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
763 | // CHECK-NEXT: T: if [B9.4] |
764 | // CHECK-NEXT: Preds (1): B10 |
765 | // CHECK-NEXT: Succs (2): B8 B7 |
766 | // CHECK: [B10] |
767 | // CHECK-NEXT: 1: a |
768 | // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) |
769 | // WARNINGS-NEXT: 3: [B10.2] (CXXConstructExpr, class A) |
770 | // ANALYZER-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], class A) |
771 | // CHECK-NEXT: 4: A b = a; |
772 | // CHECK-NEXT: 5: b |
773 | // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) |
774 | // CHECK-NEXT: 7: [B10.6].operator int |
775 | // CHECK-NEXT: 8: [B10.6] |
776 | // CHECK-NEXT: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) |
777 | // CHECK: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
778 | // CHECK-NEXT: T: while [B10.10] |
779 | // CHECK-NEXT: Preds (2): B2 B11 |
780 | // CHECK-NEXT: Succs (2): B9 B1 |
781 | // CHECK: [B11] |
782 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
783 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B11.2], class A) |
784 | // CHECK-NEXT: 2: A a; |
785 | // CHECK-NEXT: Preds (1): B12 |
786 | // CHECK-NEXT: Succs (1): B10 |
787 | // CHECK: [B0 (EXIT)] |
788 | // CHECK-NEXT: Preds (2): B1 B4 |
789 | void test_while_jumps() { |
790 | A a; |
791 | while (A b = a) { |
792 | A c; |
793 | if (UV) break; |
794 | if (UV) continue; |
795 | if (UV) return; |
796 | A d; |
797 | } |
798 | A e; |
799 | } |
800 | |
801 | // CHECK: [B4 (ENTRY)] |
802 | // CHECK-NEXT: Succs (1): B2 |
803 | // CHECK: [B1] |
804 | // CHECK-NEXT: 1: UV |
805 | // CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
806 | // CHECK-NEXT: T: do ... while [B1.2] |
807 | // CHECK-NEXT: Preds (1): B2 |
808 | // CHECK-NEXT: Succs (2): B3 B0 |
809 | // CHECK: [B2] |
810 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
811 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
812 | // CHECK-NEXT: 2: A a; |
813 | // CHECK-NEXT: 3: [B2.2].~A() (Implicit destructor) |
814 | // CHECK-NEXT: Preds (2): B3 B4 |
815 | // CHECK-NEXT: Succs (1): B1 |
816 | // CHECK: [B3] |
817 | // CHECK-NEXT: Preds (1): B1 |
818 | // CHECK-NEXT: Succs (1): B2 |
819 | // CHECK: [B0 (EXIT)] |
820 | // CHECK-NEXT: Preds (1): B1 |
821 | void test_do_implicit_scope() { |
822 | do A a; |
823 | while (UV); |
824 | } |
825 | |
826 | // CHECK: [B12 (ENTRY)] |
827 | // CHECK-NEXT: Succs (1): B11 |
828 | // CHECK: [B1] |
829 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
830 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], class A) |
831 | // CHECK-NEXT: 2: A d; |
832 | // CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor) |
833 | // CHECK-NEXT: 4: [B11.2].~A() (Implicit destructor) |
834 | // CHECK-NEXT: Preds (2): B8 B2 |
835 | // CHECK-NEXT: Succs (1): B0 |
836 | // CHECK: [B2] |
837 | // CHECK-NEXT: 1: UV |
838 | // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
839 | // CHECK-NEXT: T: do ... while [B2.2] |
840 | // CHECK-NEXT: Preds (2): B3 B6 |
841 | // CHECK-NEXT: Succs (2): B10 B1 |
842 | // CHECK: [B3] |
843 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
844 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
845 | // CHECK-NEXT: 2: A c; |
846 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
847 | // CHECK-NEXT: 4: [B9.2].~A() (Implicit destructor) |
848 | // CHECK-NEXT: Preds (1): B5 |
849 | // CHECK-NEXT: Succs (1): B2 |
850 | // CHECK: [B4] |
851 | // CHECK-NEXT: 1: return; |
852 | // CHECK-NEXT: 2: [B9.2].~A() (Implicit destructor) |
853 | // CHECK-NEXT: 3: [B11.2].~A() (Implicit destructor) |
854 | // CHECK-NEXT: Preds (1): B5 |
855 | // CHECK-NEXT: Succs (1): B0 |
856 | // CHECK: [B5] |
857 | // CHECK-NEXT: 1: UV |
858 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
859 | // CHECK-NEXT: T: if [B5.2] |
860 | // CHECK-NEXT: Preds (1): B7 |
861 | // CHECK-NEXT: Succs (2): B4 B3 |
862 | // CHECK: [B6] |
863 | // CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) |
864 | // CHECK-NEXT: T: continue; |
865 | // CHECK: Preds (1): B7 |
866 | // CHECK-NEXT: Succs (1): B2 |
867 | // CHECK: [B7] |
868 | // CHECK-NEXT: 1: UV |
869 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
870 | // CHECK-NEXT: T: if [B7.2] |
871 | // CHECK-NEXT: Preds (1): B9 |
872 | // CHECK-NEXT: Succs (2): B6 B5 |
873 | // CHECK: [B8] |
874 | // CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) |
875 | // CHECK-NEXT: T: break; |
876 | // CHECK: Preds (1): B9 |
877 | // CHECK-NEXT: Succs (1): B1 |
878 | // CHECK: [B9] |
879 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
880 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B9.2], class A) |
881 | // CHECK-NEXT: 2: A b; |
882 | // CHECK-NEXT: 3: UV |
883 | // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
884 | // CHECK-NEXT: T: if [B9.4] |
885 | // CHECK-NEXT: Preds (2): B10 B11 |
886 | // CHECK-NEXT: Succs (2): B8 B7 |
887 | // CHECK: [B10] |
888 | // CHECK-NEXT: Preds (1): B2 |
889 | // CHECK-NEXT: Succs (1): B9 |
890 | // CHECK: [B11] |
891 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
892 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B11.2], class A) |
893 | // CHECK-NEXT: 2: A a; |
894 | // CHECK-NEXT: Preds (1): B12 |
895 | // CHECK-NEXT: Succs (1): B9 |
896 | // CHECK: [B0 (EXIT)] |
897 | // CHECK-NEXT: Preds (2): B1 B4 |
898 | void test_do_jumps() { |
899 | A a; |
900 | do { |
901 | A b; |
902 | if (UV) break; |
903 | if (UV) continue; |
904 | if (UV) return; |
905 | A c; |
906 | } while (UV); |
907 | A d; |
908 | } |
909 | |
910 | // CHECK: [B4 (ENTRY)] |
911 | // CHECK-NEXT: Succs (1): B2 |
912 | // CHECK: [B1] |
913 | // CHECK-NEXT: 1: [B2.6].~A() (Implicit destructor) |
914 | // CHECK-NEXT: 2: [B2.2].~A() (Implicit destructor) |
915 | // CHECK-NEXT: Preds (2): B3 B2 |
916 | // CHECK-NEXT: Succs (1): B0 |
917 | // CHECK: [B2] |
918 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
919 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
920 | // CHECK-NEXT: 2: A a; |
921 | // CHECK-NEXT: 3: a |
922 | // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class A) |
923 | // CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class A) |
924 | // CHECK-NEXT: 6: A b = a; |
925 | // CHECK-NEXT: 7: b |
926 | // CHECK-NEXT: 8: [B2.7] (ImplicitCastExpr, NoOp, const class A) |
927 | // CHECK-NEXT: 9: [B2.8].operator int |
928 | // CHECK: 10: [B2.8] |
929 | // CHECK: 11: [B2.10] (ImplicitCastExpr, UserDefinedConversion, int) |
930 | // CHECK-NEXT: T: switch [B2.11] |
931 | // CHECK-NEXT: Preds (1): B4 |
932 | // CHECK-NEXT: Succs (1): B1 |
933 | // CHECK: [B3] |
934 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
935 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
936 | // CHECK-NEXT: 2: A c; |
937 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
938 | // CHECK-NEXT: Succs (1): B1 |
939 | // CHECK: [B0 (EXIT)] |
940 | // CHECK-NEXT: Preds (1): B1 |
941 | void test_switch_implicit_scope() { |
942 | A a; |
943 | switch (A b = a) |
944 | A c; |
945 | } |
946 | |
947 | // CHECK: [B9 (ENTRY)] |
948 | // CHECK-NEXT: Succs (1): B2 |
949 | // CHECK: [B1] |
950 | // CHECK-NEXT: 1: [B2.6].~A() (Implicit destructor) |
951 | // WARNINGS-NEXT: 2: (CXXConstructExpr, class A) |
952 | // ANALYZER-NEXT: 2: (CXXConstructExpr, [B1.3], class A) |
953 | // CHECK-NEXT: 3: A g; |
954 | // CHECK-NEXT: 4: [B1.3].~A() (Implicit destructor) |
955 | // CHECK-NEXT: 5: [B2.2].~A() (Implicit destructor) |
956 | // CHECK-NEXT: Preds (3): B3 B7 B2 |
957 | // CHECK-NEXT: Succs (1): B0 |
958 | // CHECK: [B2] |
959 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
960 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B2.2], class A) |
961 | // CHECK-NEXT: 2: A a; |
962 | // CHECK-NEXT: 3: a |
963 | // CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class A) |
964 | // CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class A) |
965 | // CHECK-NEXT: 6: A b = a; |
966 | // CHECK-NEXT: 7: b |
967 | // CHECK-NEXT: 8: [B2.7] (ImplicitCastExpr, NoOp, const class A) |
968 | // CHECK-NEXT: 9: [B2.8].operator int |
969 | // CHECK: 10: [B2.8] |
970 | // CHECK: 11: [B2.10] (ImplicitCastExpr, UserDefinedConversion, int) |
971 | // CHECK-NEXT: T: switch [B2.11] |
972 | // CHECK-NEXT: Preds (1): B9 |
973 | // CHECK-NEXT: Succs (3): B3 B8 B1 |
974 | // CHECK: [B3] |
975 | // CHECK: case 1: |
976 | // CHECK-NEXT: T: break; |
977 | // CHECK: Preds (2): B2 B4 |
978 | // CHECK-NEXT: Succs (1): B1 |
979 | // CHECK: [B4] |
980 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
981 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B4.2], class A) |
982 | // CHECK-NEXT: 2: A f; |
983 | // CHECK-NEXT: 3: [B4.2].~A() (Implicit destructor) |
984 | // CHECK-NEXT: 4: [B8.2].~A() (Implicit destructor) |
985 | // CHECK-NEXT: Preds (1): B6 |
986 | // CHECK-NEXT: Succs (1): B3 |
987 | // CHECK: [B5] |
988 | // CHECK-NEXT: 1: return; |
989 | // CHECK-NEXT: 2: [B8.2].~A() (Implicit destructor) |
990 | // CHECK-NEXT: 3: [B2.6].~A() (Implicit destructor) |
991 | // CHECK-NEXT: 4: [B2.2].~A() (Implicit destructor) |
992 | // CHECK-NEXT: Preds (1): B6 |
993 | // CHECK-NEXT: Succs (1): B0 |
994 | // CHECK: [B6] |
995 | // CHECK-NEXT: 1: UV |
996 | // CHECK-NEXT: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
997 | // CHECK-NEXT: T: if [B6.2] |
998 | // CHECK-NEXT: Preds (1): B8 |
999 | // CHECK-NEXT: Succs (2): B5 B4 |
1000 | // CHECK: [B7] |
1001 | // CHECK-NEXT: 1: [B8.2].~A() (Implicit destructor) |
1002 | // CHECK-NEXT: T: break; |
1003 | // CHECK: Preds (1): B8 |
1004 | // CHECK-NEXT: Succs (1): B1 |
1005 | // CHECK: [B8] |
1006 | // CHECK: case 0: |
1007 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
1008 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B8.2], class A) |
1009 | // CHECK-NEXT: 2: A c; |
1010 | // CHECK-NEXT: 3: UV |
1011 | // CHECK-NEXT: 4: [B8.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
1012 | // CHECK-NEXT: T: if [B8.4] |
1013 | // CHECK-NEXT: Preds (1): B2 |
1014 | // CHECK-NEXT: Succs (2): B7 B6 |
1015 | // CHECK: [B0 (EXIT)] |
1016 | // CHECK-NEXT: Preds (2): B1 B5 |
1017 | void test_switch_jumps() { |
1018 | A a; |
1019 | switch (A b = a) { |
1020 | case 0: { |
1021 | A c; |
1022 | if (UV) break; |
1023 | if (UV) return; |
1024 | A f; |
1025 | } |
1026 | case 1: |
1027 | break; |
1028 | } |
1029 | A g; |
1030 | } |
1031 | |
1032 | // CHECK: [B6 (ENTRY)] |
1033 | // CHECK-NEXT: Succs (1): B5 |
1034 | // CHECK: [B1] |
1035 | // CHECK-NEXT: 1: [B4.4].~A() (Implicit destructor) |
1036 | // CHECK-NEXT: 2: [B5.2].~A() (Implicit destructor) |
1037 | // CHECK-NEXT: Preds (1): B4 |
1038 | // CHECK-NEXT: Succs (1): B0 |
1039 | // CHECK: [B2] |
1040 | // CHECK-NEXT: Preds (1): B3 |
1041 | // CHECK-NEXT: Succs (1): B4 |
1042 | // CHECK: [B3] |
1043 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
1044 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
1045 | // CHECK-NEXT: 2: A c; |
1046 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
1047 | // CHECK-NEXT: 4: [B4.4].~A() (Implicit destructor) |
1048 | // CHECK-NEXT: Preds (1): B4 |
1049 | // CHECK-NEXT: Succs (1): B2 |
1050 | // CHECK: [B4] |
1051 | // CHECK-NEXT: 1: a |
1052 | // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) |
1053 | // WARNINGS-NEXT: 3: [B4.2] (CXXConstructExpr, class A) |
1054 | // ANALYZER-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], class A) |
1055 | // CHECK-NEXT: 4: A b = a; |
1056 | // CHECK-NEXT: 5: b |
1057 | // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) |
1058 | // CHECK-NEXT: 7: [B4.6].operator int |
1059 | // CHECK-NEXT: 8: [B4.6] |
1060 | // CHECK-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) |
1061 | // CHECK: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
1062 | // CHECK-NEXT: T: for (...; [B4.10]; ) |
1063 | // CHECK-NEXT: Preds (2): B2 B5 |
1064 | // CHECK-NEXT: Succs (2): B3 B1 |
1065 | // CHECK: [B5] |
1066 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
1067 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B5.2], class A) |
1068 | // CHECK-NEXT: 2: A a; |
1069 | // CHECK-NEXT: Preds (1): B6 |
1070 | // CHECK-NEXT: Succs (1): B4 |
1071 | // CHECK: [B0 (EXIT)] |
1072 | // CHECK-NEXT: Preds (1): B1 |
1073 | void test_for_implicit_scope() { |
1074 | for (A a; A b = a; ) |
1075 | A c; |
1076 | } |
1077 | |
1078 | // CHECK: [B12 (ENTRY)] |
1079 | // CHECK-NEXT: Succs (1): B11 |
1080 | // CHECK: [B1] |
1081 | // CHECK-NEXT: 1: [B10.4].~A() (Implicit destructor) |
1082 | // CHECK-NEXT: 2: [B11.4].~A() (Implicit destructor) |
1083 | // WARNINGS-NEXT: 3: (CXXConstructExpr, class A) |
1084 | // ANALYZER-NEXT: 3: (CXXConstructExpr, [B1.4], class A) |
1085 | // CHECK-NEXT: 4: A f; |
1086 | // CHECK-NEXT: 5: [B1.4].~A() (Implicit destructor) |
1087 | // CHECK-NEXT: 6: [B11.2].~A() (Implicit destructor) |
1088 | // CHECK-NEXT: Preds (2): B8 B10 |
1089 | // CHECK-NEXT: Succs (1): B0 |
1090 | // CHECK: [B2] |
1091 | // CHECK-NEXT: Preds (2): B3 B6 |
1092 | // CHECK-NEXT: Succs (1): B10 |
1093 | // CHECK: [B3] |
1094 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
1095 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B3.2], class A) |
1096 | // CHECK-NEXT: 2: A e; |
1097 | // CHECK-NEXT: 3: [B3.2].~A() (Implicit destructor) |
1098 | // CHECK-NEXT: 4: [B9.2].~A() (Implicit destructor) |
1099 | // CHECK-NEXT: 5: [B10.4].~A() (Implicit destructor) |
1100 | // CHECK-NEXT: Preds (1): B5 |
1101 | // CHECK-NEXT: Succs (1): B2 |
1102 | // CHECK: [B4] |
1103 | // CHECK-NEXT: 1: return; |
1104 | // CHECK-NEXT: 2: [B9.2].~A() (Implicit destructor) |
1105 | // CHECK-NEXT: 3: [B10.4].~A() (Implicit destructor) |
1106 | // CHECK-NEXT: 4: [B11.4].~A() (Implicit destructor) |
1107 | // CHECK-NEXT: 5: [B11.2].~A() (Implicit destructor) |
1108 | // CHECK-NEXT: Preds (1): B5 |
1109 | // CHECK-NEXT: Succs (1): B0 |
1110 | // CHECK: [B5] |
1111 | // CHECK-NEXT: 1: UV |
1112 | // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
1113 | // CHECK-NEXT: T: if [B5.2] |
1114 | // CHECK-NEXT: Preds (1): B7 |
1115 | // CHECK-NEXT: Succs (2): B4 B3 |
1116 | // CHECK: [B6] |
1117 | // CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) |
1118 | // CHECK-NEXT: T: continue; |
1119 | // CHECK: Preds (1): B7 |
1120 | // CHECK-NEXT: Succs (1): B2 |
1121 | // CHECK: [B7] |
1122 | // CHECK-NEXT: 1: UV |
1123 | // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) |
1124 | // CHECK-NEXT: T: if [B7.2] |
1125 | // CHECK-NEXT: Preds (1): B9 |
1126 | // CHECK-NEXT: Succs (2): B6 B5 |
1127 | // CHECK: [B8] |
1128 | // CHECK-NEXT: 1: [B9.2].~A() (Implicit destructor) |
1129 | // CHECK-NEXT: T: break; |
1130 | // CHECK: Preds (1): B9 |
1131 | // CHECK-NEXT: Succs (1): B1 |
1132 | // CHECK: [B9] |
1133 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
1134 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B9.2], class A) |
1135 | // CHECK-NEXT: 2: A d; |
1136 | // CHECK-NEXT: 3: UV |
1137 | // CHECK-NEXT: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) |
1138 | // CHECK-NEXT: T: if [B9.4] |
1139 | // CHECK-NEXT: Preds (1): B10 |
1140 | // CHECK-NEXT: Succs (2): B8 B7 |
1141 | // CHECK: [B10] |
1142 | // CHECK-NEXT: 1: b |
1143 | // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) |
1144 | // WARNINGS-NEXT: 3: [B10.2] (CXXConstructExpr, class A) |
1145 | // ANALYZER-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], class A) |
1146 | // CHECK-NEXT: 4: A c = b; |
1147 | // CHECK-NEXT: 5: c |
1148 | // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) |
1149 | // CHECK-NEXT: 7: [B10.6].operator int |
1150 | // CHECK-NEXT: 8: [B10.6] |
1151 | // CHECK-NEXT: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) |
1152 | // CHECK: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) |
1153 | // CHECK-NEXT: T: for (...; [B10.10]; ) |
1154 | // CHECK-NEXT: Preds (2): B2 B11 |
1155 | // CHECK-NEXT: Succs (2): B9 B1 |
1156 | // CHECK: [B11] |
1157 | // WARNINGS-NEXT: 1: (CXXConstructExpr, class A) |
1158 | // ANALYZER-NEXT: 1: (CXXConstructExpr, [B11.2], class A) |
1159 | // CHECK-NEXT: 2: A a; |
1160 | // WARNINGS-NEXT: 3: (CXXConstructExpr, class A) |
1161 | // ANALYZER-NEXT: 3: (CXXConstructExpr, [B11.4], class A) |
1162 | // CHECK-NEXT: 4: A b; |
1163 | // CHECK-NEXT: Preds (1): B12 |
1164 | // CHECK-NEXT: Succs (1): B10 |
1165 | // CHECK: [B0 (EXIT)] |
1166 | // CHECK-NEXT: Preds (2): B1 B4 |
1167 | void test_for_jumps() { |
1168 | A a; |
1169 | for (A b; A c = b; ) { |
1170 | A d; |
1171 | if (UV) break; |
1172 | if (UV) continue; |
1173 | if (UV) return; |
1174 | A e; |
1175 | } |
1176 | A f; |
1177 | } |
1178 | |
1179 | // CHECK: [B3 (ENTRY)] |
1180 | // CHECK-NEXT: Succs (1): B0 |
1181 | // CHECK: [B1] |
1182 | // CHECK-NEXT: T: try ... |
1183 | // CHECK-NEXT: Succs (2): B2 B0 |
1184 | // CHECK: [B2] |
1185 | // CHECK-NEXT: catch (const A &e): |
1186 | // CHECK-NEXT: 1: catch (const A &e) { |
1187 | // CHECK-NEXT: } |
1188 | // CHECK-NEXT: Preds (1): B1 |
1189 | // CHECK-NEXT: Succs (1): B0 |
1190 | // CHECK: [B0 (EXIT)] |
1191 | // CHECK-NEXT: Preds (3): B2 B1 B3 |
1192 | void test_catch_const_ref() { |
1193 | try { |
1194 | } catch (const A& e) { |
1195 | } |
1196 | } |
1197 | |
1198 | // CHECK: [B3 (ENTRY)] |
1199 | // CHECK-NEXT: Succs (1): B0 |
1200 | // CHECK: [B1] |
1201 | // CHECK-NEXT: T: try ... |
1202 | // CHECK-NEXT: Succs (2): B2 B0 |
1203 | // CHECK: [B2] |
1204 | // CHECK-NEXT: catch (A e): |
1205 | // CHECK-NEXT: 1: catch (A e) { |
1206 | // CHECK-NEXT: } |
1207 | // CHECK-NEXT: 2: [B2.1].~A() (Implicit destructor) |
1208 | // CHECK-NEXT: Preds (1): B1 |
1209 | // CHECK-NEXT: Succs (1): B0 |
1210 | // CHECK: [B0 (EXIT)] |
1211 | // CHECK-NEXT: Preds (3): B2 B1 B3 |
1212 | void test_catch_copy() { |
1213 | try { |
1214 | } catch (A e) { |
1215 | } |
1216 | } |
1217 | |