annotate clang/test/Analysis/copy-elision.cpp @ 222:81f6424ef0e3 llvm-original

LLVM original branch
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 18 Jul 2021 22:10:01 +0900 (2021-07-18)
parents 1d019706d866
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -verify -analyzer-config eagerly-assume=false %s
anatofuz
parents:
diff changeset
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -verify -analyzer-config eagerly-assume=false %s
anatofuz
parents:
diff changeset
3 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++11 -analyzer-config elide-constructors=false -DNO_ELIDE_FLAG -verify -analyzer-config eagerly-assume=false %s
anatofuz
parents:
diff changeset
4 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -std=c++17 -analyzer-config elide-constructors=false -DNO_ELIDE_FLAG -verify -analyzer-config eagerly-assume=false %s
anatofuz
parents:
diff changeset
5
anatofuz
parents:
diff changeset
6 // Copy elision always occurs in C++17, otherwise it's under
anatofuz
parents:
diff changeset
7 // an on-by-default flag.
anatofuz
parents:
diff changeset
8 #if __cplusplus >= 201703L
anatofuz
parents:
diff changeset
9 #define ELIDE 1
anatofuz
parents:
diff changeset
10 #else
anatofuz
parents:
diff changeset
11 #ifndef NO_ELIDE_FLAG
anatofuz
parents:
diff changeset
12 #define ELIDE 1
anatofuz
parents:
diff changeset
13 #endif
anatofuz
parents:
diff changeset
14 #endif
anatofuz
parents:
diff changeset
15
anatofuz
parents:
diff changeset
16 void clang_analyzer_eval(bool);
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 namespace variable_functional_cast_crash {
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 struct A {
anatofuz
parents:
diff changeset
21 A(int) {}
anatofuz
parents:
diff changeset
22 };
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 void foo() {
anatofuz
parents:
diff changeset
25 A a = A(0);
anatofuz
parents:
diff changeset
26 }
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 struct B {
anatofuz
parents:
diff changeset
29 A a;
anatofuz
parents:
diff changeset
30 B(): a(A(0)) {}
anatofuz
parents:
diff changeset
31 };
anatofuz
parents:
diff changeset
32
anatofuz
parents:
diff changeset
33 } // namespace variable_functional_cast_crash
anatofuz
parents:
diff changeset
34
anatofuz
parents:
diff changeset
35
anatofuz
parents:
diff changeset
36 namespace ctor_initializer {
anatofuz
parents:
diff changeset
37
anatofuz
parents:
diff changeset
38 struct S {
anatofuz
parents:
diff changeset
39 int x, y, z;
anatofuz
parents:
diff changeset
40 };
anatofuz
parents:
diff changeset
41
anatofuz
parents:
diff changeset
42 struct T {
anatofuz
parents:
diff changeset
43 S s;
anatofuz
parents:
diff changeset
44 int w;
anatofuz
parents:
diff changeset
45 T(int w): s(), w(w) {}
anatofuz
parents:
diff changeset
46 };
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 class C {
anatofuz
parents:
diff changeset
49 T t;
anatofuz
parents:
diff changeset
50 public:
anatofuz
parents:
diff changeset
51 C() : t(T(4)) {
anatofuz
parents:
diff changeset
52 S s = {1, 2, 3};
anatofuz
parents:
diff changeset
53 t.s = s;
anatofuz
parents:
diff changeset
54 // FIXME: Should be TRUE regardless of copy elision.
anatofuz
parents:
diff changeset
55 clang_analyzer_eval(t.w == 4);
anatofuz
parents:
diff changeset
56 #ifdef ELIDE
anatofuz
parents:
diff changeset
57 // expected-warning@-2{{TRUE}}
anatofuz
parents:
diff changeset
58 #else
anatofuz
parents:
diff changeset
59 // expected-warning@-4{{UNKNOWN}}
anatofuz
parents:
diff changeset
60 #endif
anatofuz
parents:
diff changeset
61 }
anatofuz
parents:
diff changeset
62 };
anatofuz
parents:
diff changeset
63
anatofuz
parents:
diff changeset
64
anatofuz
parents:
diff changeset
65 struct A {
anatofuz
parents:
diff changeset
66 int x;
anatofuz
parents:
diff changeset
67 A(): x(0) {}
anatofuz
parents:
diff changeset
68 ~A() {}
anatofuz
parents:
diff changeset
69 };
anatofuz
parents:
diff changeset
70
anatofuz
parents:
diff changeset
71 struct B {
anatofuz
parents:
diff changeset
72 A a;
anatofuz
parents:
diff changeset
73 B() : a(A()) {}
anatofuz
parents:
diff changeset
74 };
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 void foo() {
anatofuz
parents:
diff changeset
77 B b;
anatofuz
parents:
diff changeset
78 clang_analyzer_eval(b.a.x == 0); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
79 }
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 } // namespace ctor_initializer
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 namespace elision_on_ternary_op_branches {
anatofuz
parents:
diff changeset
85 class C1 {
anatofuz
parents:
diff changeset
86 int x;
anatofuz
parents:
diff changeset
87 public:
anatofuz
parents:
diff changeset
88 C1(int x): x(x) {}
anatofuz
parents:
diff changeset
89 int getX() const { return x; }
anatofuz
parents:
diff changeset
90 ~C1();
anatofuz
parents:
diff changeset
91 };
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 class C2 {
anatofuz
parents:
diff changeset
94 int x;
anatofuz
parents:
diff changeset
95 int y;
anatofuz
parents:
diff changeset
96 public:
anatofuz
parents:
diff changeset
97 C2(int x, int y): x(x), y(y) {}
anatofuz
parents:
diff changeset
98 int getX() const { return x; }
anatofuz
parents:
diff changeset
99 int getY() const { return y; }
anatofuz
parents:
diff changeset
100 ~C2();
anatofuz
parents:
diff changeset
101 };
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 void foo(int coin) {
anatofuz
parents:
diff changeset
104 C1 c1 = coin ? C1(1) : C1(2);
anatofuz
parents:
diff changeset
105 if (coin) {
anatofuz
parents:
diff changeset
106 clang_analyzer_eval(c1.getX() == 1); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
107 } else {
anatofuz
parents:
diff changeset
108 clang_analyzer_eval(c1.getX() == 2); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
109 }
anatofuz
parents:
diff changeset
110 C2 c2 = coin ? C2(3, 4) : C2(5, 6);
anatofuz
parents:
diff changeset
111 if (coin) {
anatofuz
parents:
diff changeset
112 clang_analyzer_eval(c2.getX() == 3); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
113 clang_analyzer_eval(c2.getY() == 4); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
114 } else {
anatofuz
parents:
diff changeset
115 clang_analyzer_eval(c2.getX() == 5); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
116 clang_analyzer_eval(c2.getY() == 6); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
117 }
anatofuz
parents:
diff changeset
118 }
anatofuz
parents:
diff changeset
119 } // namespace elision_on_ternary_op_branches
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121
anatofuz
parents:
diff changeset
122 namespace address_vector_tests {
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 template <typename T> struct AddressVector {
anatofuz
parents:
diff changeset
125 T *buf[20];
anatofuz
parents:
diff changeset
126 int len;
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 AddressVector() : len(0) {}
anatofuz
parents:
diff changeset
129
anatofuz
parents:
diff changeset
130 void push(T *t) {
anatofuz
parents:
diff changeset
131 buf[len] = t;
anatofuz
parents:
diff changeset
132 ++len;
anatofuz
parents:
diff changeset
133 }
anatofuz
parents:
diff changeset
134 };
anatofuz
parents:
diff changeset
135
anatofuz
parents:
diff changeset
136 class ClassWithoutDestructor {
anatofuz
parents:
diff changeset
137 AddressVector<ClassWithoutDestructor> &v;
anatofuz
parents:
diff changeset
138
anatofuz
parents:
diff changeset
139 public:
anatofuz
parents:
diff changeset
140 ClassWithoutDestructor(AddressVector<ClassWithoutDestructor> &v) : v(v) {
anatofuz
parents:
diff changeset
141 push();
anatofuz
parents:
diff changeset
142 }
anatofuz
parents:
diff changeset
143
anatofuz
parents:
diff changeset
144 ClassWithoutDestructor(ClassWithoutDestructor &&c) : v(c.v) { push(); }
anatofuz
parents:
diff changeset
145 ClassWithoutDestructor(const ClassWithoutDestructor &c) : v(c.v) { push(); }
anatofuz
parents:
diff changeset
146
anatofuz
parents:
diff changeset
147 void push() { v.push(this); }
anatofuz
parents:
diff changeset
148 };
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 ClassWithoutDestructor make1(AddressVector<ClassWithoutDestructor> &v) {
anatofuz
parents:
diff changeset
151 return ClassWithoutDestructor(v);
anatofuz
parents:
diff changeset
152 }
anatofuz
parents:
diff changeset
153 ClassWithoutDestructor make2(AddressVector<ClassWithoutDestructor> &v) {
anatofuz
parents:
diff changeset
154 return make1(v);
anatofuz
parents:
diff changeset
155 }
anatofuz
parents:
diff changeset
156 ClassWithoutDestructor make3(AddressVector<ClassWithoutDestructor> &v) {
anatofuz
parents:
diff changeset
157 return make2(v);
anatofuz
parents:
diff changeset
158 }
anatofuz
parents:
diff changeset
159
anatofuz
parents:
diff changeset
160 void testMultipleReturns() {
anatofuz
parents:
diff changeset
161 AddressVector<ClassWithoutDestructor> v;
anatofuz
parents:
diff changeset
162 ClassWithoutDestructor c = make3(v);
anatofuz
parents:
diff changeset
163
anatofuz
parents:
diff changeset
164 #if ELIDE
anatofuz
parents:
diff changeset
165 clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
166 clang_analyzer_eval(v.buf[0] == &c); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
167 #else
anatofuz
parents:
diff changeset
168 clang_analyzer_eval(v.len == 5); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
169 clang_analyzer_eval(v.buf[0] != v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
170 clang_analyzer_eval(v.buf[1] != v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
171 clang_analyzer_eval(v.buf[2] != v.buf[3]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
172 clang_analyzer_eval(v.buf[3] != v.buf[4]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
173 clang_analyzer_eval(v.buf[4] == &c); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
174 #endif
anatofuz
parents:
diff changeset
175 }
anatofuz
parents:
diff changeset
176
anatofuz
parents:
diff changeset
177 void consume(ClassWithoutDestructor c) {
anatofuz
parents:
diff changeset
178 c.push();
anatofuz
parents:
diff changeset
179 }
anatofuz
parents:
diff changeset
180
anatofuz
parents:
diff changeset
181 void testArgumentConstructorWithoutDestructor() {
anatofuz
parents:
diff changeset
182 AddressVector<ClassWithoutDestructor> v;
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 consume(make3(v));
anatofuz
parents:
diff changeset
185
anatofuz
parents:
diff changeset
186 #if ELIDE
anatofuz
parents:
diff changeset
187 clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
188 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
189 #else
anatofuz
parents:
diff changeset
190 clang_analyzer_eval(v.len == 6); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
191 clang_analyzer_eval(v.buf[0] != v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
192 clang_analyzer_eval(v.buf[1] != v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
193 clang_analyzer_eval(v.buf[2] != v.buf[3]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
194 clang_analyzer_eval(v.buf[3] != v.buf[4]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
195 // We forced a push() in consume(), let's see if the address here matches
anatofuz
parents:
diff changeset
196 // the address during construction.
anatofuz
parents:
diff changeset
197 clang_analyzer_eval(v.buf[4] == v.buf[5]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
198 #endif
anatofuz
parents:
diff changeset
199 }
anatofuz
parents:
diff changeset
200
anatofuz
parents:
diff changeset
201 class ClassWithDestructor {
anatofuz
parents:
diff changeset
202 AddressVector<ClassWithDestructor> &v;
anatofuz
parents:
diff changeset
203
anatofuz
parents:
diff changeset
204 public:
anatofuz
parents:
diff changeset
205 ClassWithDestructor(AddressVector<ClassWithDestructor> &v) : v(v) {
anatofuz
parents:
diff changeset
206 push();
anatofuz
parents:
diff changeset
207 }
anatofuz
parents:
diff changeset
208
anatofuz
parents:
diff changeset
209 ClassWithDestructor(ClassWithDestructor &&c) : v(c.v) { push(); }
anatofuz
parents:
diff changeset
210 ClassWithDestructor(const ClassWithDestructor &c) : v(c.v) { push(); }
anatofuz
parents:
diff changeset
211
anatofuz
parents:
diff changeset
212 ~ClassWithDestructor() { push(); }
anatofuz
parents:
diff changeset
213
anatofuz
parents:
diff changeset
214 void push() { v.push(this); }
anatofuz
parents:
diff changeset
215 };
anatofuz
parents:
diff changeset
216
anatofuz
parents:
diff changeset
217 void testVariable() {
anatofuz
parents:
diff changeset
218 AddressVector<ClassWithDestructor> v;
anatofuz
parents:
diff changeset
219 {
anatofuz
parents:
diff changeset
220 ClassWithDestructor c = ClassWithDestructor(v);
anatofuz
parents:
diff changeset
221 // Check if the last destructor is an automatic destructor.
anatofuz
parents:
diff changeset
222 // A temporary destructor would have fired by now.
anatofuz
parents:
diff changeset
223 #if ELIDE
anatofuz
parents:
diff changeset
224 clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
225 #else
anatofuz
parents:
diff changeset
226 clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
227 #endif
anatofuz
parents:
diff changeset
228 }
anatofuz
parents:
diff changeset
229 #if ELIDE
anatofuz
parents:
diff changeset
230 // 0. Construct the variable.
anatofuz
parents:
diff changeset
231 // 1. Destroy the variable.
anatofuz
parents:
diff changeset
232 clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
233 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
234 #else
anatofuz
parents:
diff changeset
235 // 0. Construct the temporary.
anatofuz
parents:
diff changeset
236 // 1. Construct the variable.
anatofuz
parents:
diff changeset
237 // 2. Destroy the temporary.
anatofuz
parents:
diff changeset
238 // 3. Destroy the variable.
anatofuz
parents:
diff changeset
239 clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
240 clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
241 clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
242 #endif
anatofuz
parents:
diff changeset
243 }
anatofuz
parents:
diff changeset
244
anatofuz
parents:
diff changeset
245 struct TestCtorInitializer {
anatofuz
parents:
diff changeset
246 ClassWithDestructor c;
anatofuz
parents:
diff changeset
247 TestCtorInitializer(AddressVector<ClassWithDestructor> &v)
anatofuz
parents:
diff changeset
248 : c(ClassWithDestructor(v)) {}
anatofuz
parents:
diff changeset
249 };
anatofuz
parents:
diff changeset
250
anatofuz
parents:
diff changeset
251 void testCtorInitializer() {
anatofuz
parents:
diff changeset
252 AddressVector<ClassWithDestructor> v;
anatofuz
parents:
diff changeset
253 {
anatofuz
parents:
diff changeset
254 TestCtorInitializer t(v);
anatofuz
parents:
diff changeset
255 // Check if the last destructor is an automatic destructor.
anatofuz
parents:
diff changeset
256 // A temporary destructor would have fired by now.
anatofuz
parents:
diff changeset
257 #if ELIDE
anatofuz
parents:
diff changeset
258 clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
259 #else
anatofuz
parents:
diff changeset
260 clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
261 #endif
anatofuz
parents:
diff changeset
262 }
anatofuz
parents:
diff changeset
263 #if ELIDE
anatofuz
parents:
diff changeset
264 // 0. Construct the member variable.
anatofuz
parents:
diff changeset
265 // 1. Destroy the member variable.
anatofuz
parents:
diff changeset
266 clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
267 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
268 #else
anatofuz
parents:
diff changeset
269 // 0. Construct the temporary.
anatofuz
parents:
diff changeset
270 // 1. Construct the member variable.
anatofuz
parents:
diff changeset
271 // 2. Destroy the temporary.
anatofuz
parents:
diff changeset
272 // 3. Destroy the member variable.
anatofuz
parents:
diff changeset
273 clang_analyzer_eval(v.len == 4); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
274 clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
275 clang_analyzer_eval(v.buf[1] == v.buf[3]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
276 #endif
anatofuz
parents:
diff changeset
277 }
anatofuz
parents:
diff changeset
278
anatofuz
parents:
diff changeset
279
anatofuz
parents:
diff changeset
280 ClassWithDestructor make1(AddressVector<ClassWithDestructor> &v) {
anatofuz
parents:
diff changeset
281 return ClassWithDestructor(v);
anatofuz
parents:
diff changeset
282 }
anatofuz
parents:
diff changeset
283 ClassWithDestructor make2(AddressVector<ClassWithDestructor> &v) {
anatofuz
parents:
diff changeset
284 return make1(v);
anatofuz
parents:
diff changeset
285 }
anatofuz
parents:
diff changeset
286 ClassWithDestructor make3(AddressVector<ClassWithDestructor> &v) {
anatofuz
parents:
diff changeset
287 return make2(v);
anatofuz
parents:
diff changeset
288 }
anatofuz
parents:
diff changeset
289
anatofuz
parents:
diff changeset
290 void testMultipleReturnsWithDestructors() {
anatofuz
parents:
diff changeset
291 AddressVector<ClassWithDestructor> v;
anatofuz
parents:
diff changeset
292 {
anatofuz
parents:
diff changeset
293 ClassWithDestructor c = make3(v);
anatofuz
parents:
diff changeset
294 // Check if the last destructor is an automatic destructor.
anatofuz
parents:
diff changeset
295 // A temporary destructor would have fired by now.
anatofuz
parents:
diff changeset
296 #if ELIDE
anatofuz
parents:
diff changeset
297 clang_analyzer_eval(v.len == 1); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
298 #else
anatofuz
parents:
diff changeset
299 clang_analyzer_eval(v.len == 9); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
300 #endif
anatofuz
parents:
diff changeset
301 }
anatofuz
parents:
diff changeset
302
anatofuz
parents:
diff changeset
303 #if ELIDE
anatofuz
parents:
diff changeset
304 // 0. Construct the variable. Yes, constructor in make1() constructs
anatofuz
parents:
diff changeset
305 // the variable 'c'.
anatofuz
parents:
diff changeset
306 // 1. Destroy the variable.
anatofuz
parents:
diff changeset
307 clang_analyzer_eval(v.len == 2); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
308 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
309 #else
anatofuz
parents:
diff changeset
310 // 0. Construct the temporary in make1().
anatofuz
parents:
diff changeset
311 // 1. Construct the temporary in make2().
anatofuz
parents:
diff changeset
312 // 2. Destroy the temporary in make1().
anatofuz
parents:
diff changeset
313 // 3. Construct the temporary in make3().
anatofuz
parents:
diff changeset
314 // 4. Destroy the temporary in make2().
anatofuz
parents:
diff changeset
315 // 5. Construct the temporary here.
anatofuz
parents:
diff changeset
316 // 6. Destroy the temporary in make3().
anatofuz
parents:
diff changeset
317 // 7. Construct the variable.
anatofuz
parents:
diff changeset
318 // 8. Destroy the temporary here.
anatofuz
parents:
diff changeset
319 // 9. Destroy the variable.
anatofuz
parents:
diff changeset
320 clang_analyzer_eval(v.len == 10); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
321 clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
322 clang_analyzer_eval(v.buf[1] == v.buf[4]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
323 clang_analyzer_eval(v.buf[3] == v.buf[6]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
324 clang_analyzer_eval(v.buf[5] == v.buf[8]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
325 clang_analyzer_eval(v.buf[7] == v.buf[9]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
326 #endif
anatofuz
parents:
diff changeset
327 }
anatofuz
parents:
diff changeset
328
anatofuz
parents:
diff changeset
329 void consume(ClassWithDestructor c) {
anatofuz
parents:
diff changeset
330 c.push();
anatofuz
parents:
diff changeset
331 }
anatofuz
parents:
diff changeset
332
anatofuz
parents:
diff changeset
333 void testArgumentConstructorWithDestructor() {
anatofuz
parents:
diff changeset
334 AddressVector<ClassWithDestructor> v;
anatofuz
parents:
diff changeset
335
anatofuz
parents:
diff changeset
336 consume(make3(v));
anatofuz
parents:
diff changeset
337
anatofuz
parents:
diff changeset
338 #if ELIDE
anatofuz
parents:
diff changeset
339 // 0. Construct the argument.
anatofuz
parents:
diff changeset
340 // 1. Forced push() in consume().
anatofuz
parents:
diff changeset
341 // 2. Destroy the argument.
anatofuz
parents:
diff changeset
342 clang_analyzer_eval(v.len == 3); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
343 clang_analyzer_eval(v.buf[0] == v.buf[1]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
344 clang_analyzer_eval(v.buf[1] == v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
345 #else
anatofuz
parents:
diff changeset
346 // 0. Construct the temporary in make1().
anatofuz
parents:
diff changeset
347 // 1. Construct the temporary in make2().
anatofuz
parents:
diff changeset
348 // 2. Destroy the temporary in make1().
anatofuz
parents:
diff changeset
349 // 3. Construct the temporary in make3().
anatofuz
parents:
diff changeset
350 // 4. Destroy the temporary in make2().
anatofuz
parents:
diff changeset
351 // 5. Construct the temporary here.
anatofuz
parents:
diff changeset
352 // 6. Destroy the temporary in make3().
anatofuz
parents:
diff changeset
353 // 7. Construct the argument.
anatofuz
parents:
diff changeset
354 // 8. Forced push() in consume().
anatofuz
parents:
diff changeset
355 // 9. Destroy the argument. Notice the reverse order!
anatofuz
parents:
diff changeset
356 // 10. Destroy the temporary here.
anatofuz
parents:
diff changeset
357 clang_analyzer_eval(v.len == 11); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
358 clang_analyzer_eval(v.buf[0] == v.buf[2]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
359 clang_analyzer_eval(v.buf[1] == v.buf[4]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
360 clang_analyzer_eval(v.buf[3] == v.buf[6]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
361 clang_analyzer_eval(v.buf[5] == v.buf[10]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
362 clang_analyzer_eval(v.buf[7] == v.buf[8]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
363 clang_analyzer_eval(v.buf[8] == v.buf[9]); // expected-warning{{TRUE}}
anatofuz
parents:
diff changeset
364 #endif
anatofuz
parents:
diff changeset
365 }
anatofuz
parents:
diff changeset
366
anatofuz
parents:
diff changeset
367 } // namespace address_vector_tests