1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify -analyzer-config display-checker-name=false
2
3 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify -analyzer-config display-checker-name=false
4
5 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify -analyzer-config display-checker-name=false
6
7 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify -analyzer-config display-checker-name=false
8
9 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify -analyzer-config display-checker-name=false
10
11 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s
12
13 #include "Inputs/system-header-simulator-cxx.h"
14
15 template <typename Container>
16 long clang_analyzer_container_begin(const Container&);
17 template <typename Container>
18 long clang_analyzer_container_end(const Container&);
19 template <typename Iterator>
20 long clang_analyzer_iterator_position(const Iterator&);
21 long clang_analyzer_iterator_position(int*);
22 template <typename Iterator>
23 void* clang_analyzer_iterator_container(const Iterator&);
24 template <typename Iterator>
25 bool clang_analyzer_iterator_validity(const Iterator&);
26
27 void clang_analyzer_denote(long, const char*);
28 void clang_analyzer_express(long);
29 void clang_analyzer_eval(bool);
30 void clang_analyzer_warnIfReached();
31
begin(const std::vector<int> & v)32 void begin(const std::vector<int> &v) {
33 auto i = v.begin();
34
35 clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}}
36 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
37 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin(){{$}}}}
38
39 if (i != v.begin()) {
40 clang_analyzer_warnIfReached();
41 }
42 }
43
end(const std::vector<int> & v)44 void end(const std::vector<int> &v) {
45 auto i = v.end();
46
47 clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}}
48 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
49 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end(){{$}}}}
50
51 if (i != v.end()) {
52 clang_analyzer_warnIfReached();
53 }
54 }
55
prefix_increment(const std::vector<int> & v)56 void prefix_increment(const std::vector<int> &v) {
57 auto i = v.begin();
58
59 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
60
61 auto j = ++i;
62
63 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}}
64 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 1{{$}}}}
65 }
66
prefix_decrement(const std::vector<int> & v)67 void prefix_decrement(const std::vector<int> &v) {
68 auto i = v.end();
69
70 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
71
72 auto j = --i;
73
74 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}}
75 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 1{{$}}}}
76 }
77
postfix_increment(const std::vector<int> & v)78 void postfix_increment(const std::vector<int> &v) {
79 auto i = v.begin();
80
81 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
82
83 auto j = i++;
84
85 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}}
86 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin(){{$}}}}
87 }
88
postfix_decrement(const std::vector<int> & v)89 void postfix_decrement(const std::vector<int> &v) {
90 auto i = v.end();
91
92 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
93
94 auto j = i--;
95
96 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}}
97 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end(){{$}}}}
98 }
99
plus_equal(const std::vector<int> & v)100 void plus_equal(const std::vector<int> &v) {
101 auto i = v.begin();
102
103 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
104
105 i += 2;
106
107 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 2{{$}}}}
108 }
109
plus_equal_negative(const std::vector<int> & v)110 void plus_equal_negative(const std::vector<int> &v) {
111 auto i = v.end();
112
113 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
114
115 i += -2;
116
117 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 2{{$}}}}
118 }
119
minus_equal(const std::vector<int> & v)120 void minus_equal(const std::vector<int> &v) {
121 auto i = v.end();
122
123 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
124
125 i -= 2;
126
127 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 2{{$}}}}
128 }
129
minus_equal_negative(const std::vector<int> & v)130 void minus_equal_negative(const std::vector<int> &v) {
131 auto i = v.begin();
132
133 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
134
135 i -= -2;
136
137 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 2{{$}}}}
138 }
139
copy(const std::vector<int> & v)140 void copy(const std::vector<int> &v) {
141 auto i1 = v.end();
142
143 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
144
145 auto i2 = i1;
146
147 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
148 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}}
149 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end(){{$}}}}
150 }
151
plus_lhs(const std::vector<int> & v)152 void plus_lhs(const std::vector<int> &v) {
153 auto i1 = v.begin();
154
155 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
156
157 auto i2 = i1 + 2;
158
159 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
160 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re{{$v.begin(){{$}}}}
161 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re{{$v.begin() + 2{{$}}}}
162 }
163
plus_rhs(const std::vector<int> & v)164 void plus_rhs(const std::vector<int> &v) {
165 auto i1 = v.begin();
166
167 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
168
169 auto i2 = 2 + i1;
170
171 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
172 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re{{$v.begin(){{$}}}}
173 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re{{$v.begin() + 2{{$}}}}
174 }
175
plus_lhs_negative(const std::vector<int> & v)176 void plus_lhs_negative(const std::vector<int> &v) {
177 auto i1 = v.end();
178
179 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
180
181 auto i2 = i1 + (-2);
182
183 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
184 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}}
185 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}}
186 }
187
plus_rhs_negative(const std::vector<int> & v)188 void plus_rhs_negative(const std::vector<int> &v) {
189 auto i1 = v.end();
190
191 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
192
193 auto i2 = (-2) + i1;
194
195 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
196 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}}
197 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}}
198 }
199
minus(const std::vector<int> & v)200 void minus(const std::vector<int> &v) {
201 auto i1 = v.end();
202
203 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
204
205 auto i2 = i1 - 2;
206
207 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
208 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}}
209 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}}
210 }
211
minus_negative(const std::vector<int> & v)212 void minus_negative(const std::vector<int> &v) {
213 auto i1 = v.begin();
214
215 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
216
217 auto i2 = i1 - (-2);
218
219 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
220 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}}
221 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin() + 2{{$}}}}
222 }
223
copy_and_increment1(const std::vector<int> & v)224 void copy_and_increment1(const std::vector<int> &v) {
225 auto i1 = v.begin();
226
227 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
228
229 auto i2 = i1;
230 ++i1;
231
232 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin() + 1{{$}}}}
233 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin(){{$}}}}
234 }
235
copy_and_increment2(const std::vector<int> & v)236 void copy_and_increment2(const std::vector<int> &v) {
237 auto i1 = v.begin();
238
239 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
240
241 auto i2 = i1;
242 ++i2;
243
244 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}}
245 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin() + 1{{$}}}}
246 }
247
copy_and_decrement1(const std::vector<int> & v)248 void copy_and_decrement1(const std::vector<int> &v) {
249 auto i1 = v.end();
250
251 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
252
253 auto i2 = i1;
254 --i1;
255
256 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end() - 1{{$}}}}
257 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end(){{$}}}}
258 }
259
copy_and_decrement2(const std::vector<int> & v)260 void copy_and_decrement2(const std::vector<int> &v) {
261 auto i1 = v.end();
262
263 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
264
265 auto i2 = i1;
266 --i2;
267
268 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}}
269 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 1{{$}}}}
270 }
271
272 /// std::advance(), std::prev(), std::next()
273
std_advance_minus(const std::vector<int> & v)274 void std_advance_minus(const std::vector<int> &v) {
275 auto i = v.end();
276
277 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
278
279 std::advance(i, -1);
280
281 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}}
282 }
283
std_advance_plus(const std::vector<int> & v)284 void std_advance_plus(const std::vector<int> &v) {
285 auto i = v.begin();
286
287 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
288
289 std::advance(i, 1);
290
291 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}}
292 }
293
std_prev(const std::vector<int> & v)294 void std_prev(const std::vector<int> &v) {
295 auto i = v.end();
296
297 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
298
299 auto j = std::prev(i);
300
301 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 1{{$}}}}
302 }
303
std_prev2(const std::vector<int> & v)304 void std_prev2(const std::vector<int> &v) {
305 auto i = v.end();
306
307 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
308
309 auto j = std::prev(i, 2);
310
311 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 2{{$}}}}
312 }
313
std_next(const std::vector<int> & v)314 void std_next(const std::vector<int> &v) {
315 auto i = v.begin();
316
317 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
318
319 auto j = std::next(i);
320
321 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 1{{$}}}}
322 }
323
std_next2(const std::vector<int> & v)324 void std_next2(const std::vector<int> &v) {
325 auto i = v.begin();
326
327 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
328
329 auto j = std::next(i, 2);
330
331 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 2{{$}}}}
332 }
333
334 ////////////////////////////////////////////////////////////////////////////////
335 ///
336 /// C O N T A I N E R A S S I G N M E N T S
337 ///
338 ////////////////////////////////////////////////////////////////////////////////
339
340 // Copy
341
list_copy_assignment(std::list<int> & L1,const std::list<int> & L2)342 void list_copy_assignment(std::list<int> &L1, const std::list<int> &L2) {
343 auto i0 = L1.cbegin();
344 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
345 L1 = L2;
346 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
347 }
348
vector_copy_assignment(std::vector<int> & V1,const std::vector<int> & V2)349 void vector_copy_assignment(std::vector<int> &V1, const std::vector<int> &V2) {
350 auto i0 = V1.cbegin();
351 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
352 V1 = V2;
353 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
354 }
355
deque_copy_assignment(std::deque<int> & D1,const std::deque<int> & D2)356 void deque_copy_assignment(std::deque<int> &D1, const std::deque<int> &D2) {
357 auto i0 = D1.cbegin();
358 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
359 D1 = D2;
360 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
361 }
362
forward_list_copy_assignment(std::forward_list<int> & FL1,const std::forward_list<int> & FL2)363 void forward_list_copy_assignment(std::forward_list<int> &FL1,
364 const std::forward_list<int> &FL2) {
365 auto i0 = FL1.cbegin();
366 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
367 FL1 = FL2;
368 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
369 }
370
371 // Move
372
list_move_assignment(std::list<int> & L1,std::list<int> & L2)373 void list_move_assignment(std::list<int> &L1, std::list<int> &L2) {
374 auto i0 = L1.cbegin(), i1 = L2.cbegin(), i2 = --L2.cend(), i3 = L2.cend();
375
376 clang_analyzer_denote(clang_analyzer_container_begin(L2), "$L2.begin()");
377 clang_analyzer_denote(clang_analyzer_container_end(L2), "$L2.end()");
378
379 L1 = std::move(L2);
380
381 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
382 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
383 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
384 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
385
386 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &L1); // expected-warning{{TRUE}}
387 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &L1); // expected-warning{{TRUE}}
388
389 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L2.begin(){{$}}}}
390 }
391
vector_move_assignment(std::vector<int> & V1,std::vector<int> & V2)392 void vector_move_assignment(std::vector<int> &V1, std::vector<int> &V2) {
393 auto i0 = V1.cbegin(), i1 = V2.cbegin(), i2 = --V2.cend(), i3 = V2.cend();
394
395 clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()");
396
397 V1 = std::move(V2);
398
399 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
400 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
401 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
402 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
403
404 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &V1); // expected-warning{{TRUE}}
405 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &V1); // expected-warning{{TRUE}}
406
407 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V2.begin(){{$}}}}
408 }
409
deque_move_assignment(std::deque<int> & D1,std::deque<int> & D2)410 void deque_move_assignment(std::deque<int> &D1, std::deque<int> &D2) {
411 auto i0 = D1.cbegin(), i1 = D2.cbegin(), i2 = --D2.cend(), i3 = D2.cend();
412
413 clang_analyzer_denote(clang_analyzer_container_begin(D2), "$D2.begin()");
414
415 D1 = std::move(D2);
416
417 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
418 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
419 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
420 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
421
422 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &D1); // expected-warning{{TRUE}}
423 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &D1); // expected-warning{{TRUE}}
424
425 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$D2.begin(){{$}}}}
426 }
427
forward_list_move_assignment(std::forward_list<int> & FL1,std::forward_list<int> & FL2)428 void forward_list_move_assignment(std::forward_list<int> &FL1,
429 std::forward_list<int> &FL2) {
430 auto i0 = FL1.cbegin(), i1 = FL2.cbegin(), i2 = FL2.cend();
431
432 clang_analyzer_denote(clang_analyzer_container_begin(FL2), "$FL2.begin()");
433
434 FL1 = std::move(FL2);
435
436 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
437 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
438 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
439
440 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &FL1); // expected-warning{{TRUE}}
441
442 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL2.begin(){{$}}}}
443 }
444
445
446 ////////////////////////////////////////////////////////////////////////////////
447 ///
448 /// C O N T A I N E R M O D I F I E R S
449 ///
450 ////////////////////////////////////////////////////////////////////////////////
451
452 /// assign()
453 ///
454 /// - Invalidates all iterators, including the past-the-end iterator for all
455 /// container types.
456
list_assign(std::list<int> & L,int n)457 void list_assign(std::list<int> &L, int n) {
458 auto i0 = L.cbegin(), i1 = L.cend();
459 L.assign(10, n);
460 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
461 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
462 }
463
vector_assign(std::vector<int> & V,int n)464 void vector_assign(std::vector<int> &V, int n) {
465 auto i0 = V.cbegin(), i1 = V.cend();
466 V.assign(10, n);
467 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
468 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
469 }
470
deque_assign(std::deque<int> & D,int n)471 void deque_assign(std::deque<int> &D, int n) {
472 auto i0 = D.cbegin(), i1 = D.cend();
473 D.assign(10, n);
474 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
475 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
476 }
477
forward_list_assign(std::forward_list<int> & FL,int n)478 void forward_list_assign(std::forward_list<int> &FL, int n) {
479 auto i0 = FL.cbegin(), i1 = FL.cend();
480 FL.assign(10, n);
481 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
482 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
483 }
484
485 /// clear()
486 ///
487 /// - Invalidates all iterators, including the past-the-end iterator for all
488 /// container types.
489
list_clear(std::list<int> & L)490 void list_clear(std::list<int> &L) {
491 auto i0 = L.cbegin(), i1 = L.cend();
492 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
493 L.clear();
494 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
495 }
496
vector_clear(std::vector<int> & V)497 void vector_clear(std::vector<int> &V) {
498 auto i0 = V.cbegin(), i1 = V.cend();
499 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
500 V.clear();
501 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
502 }
503
deque_clear(std::deque<int> & D)504 void deque_clear(std::deque<int> &D) {
505 auto i0 = D.cbegin(), i1 = D.cend();
506 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
507 D.clear();
508 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
509 }
510
forward_list_clear(std::forward_list<int> & FL)511 void forward_list_clear(std::forward_list<int> &FL) {
512 auto i0 = FL.cbegin(), i1 = FL.cend();
513 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
514 FL.clear();
515 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
516 }
517
518 /// push_back()
519 ///
520 /// - Design decision: extends containers to the ->RIGHT-> (i.e. the
521 /// past-the-end position of the container is incremented).
522 ///
523 /// - Iterator invalidation rules depend the container type.
524
525 /// std::list-like containers: No iterators are invalidated.
526
list_push_back(std::list<int> & L,int n)527 void list_push_back(std::list<int> &L, int n) {
528 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
529
530 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
531 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
532
533 L.push_back(n);
534
535 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
536 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
537 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
538
539 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
540 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}}
541 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() + 1
542 }
543
544 /// std::vector-like containers: The past-the-end iterator is invalidated.
545
vector_push_back(std::vector<int> & V,int n)546 void vector_push_back(std::vector<int> &V, int n) {
547 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
548
549 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
550 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
551
552 V.push_back(n);
553
554 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
555 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
556 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
557
558 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
559 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}}
560 }
561
562 /// std::deque-like containers: All iterators, including the past-the-end
563 /// iterator, are invalidated.
564
deque_push_back(std::deque<int> & D,int n)565 void deque_push_back(std::deque<int> &D, int n) {
566 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
567
568 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
569 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
570
571 D.push_back(n);
572
573 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
574 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
575 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
576 }
577
578 /// emplace_back()
579 ///
580 /// - Design decision: extends containers to the ->RIGHT-> (i.e. the
581 /// past-the-end position of the container is incremented).
582 ///
583 /// - Iterator invalidation rules depend the container type.
584
585 /// std::list-like containers: No iterators are invalidated.
586
list_emplace_back(std::list<int> & L,int n)587 void list_emplace_back(std::list<int> &L, int n) {
588 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
589
590 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
591 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
592
593 L.emplace_back(n);
594
595 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
596 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
597 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
598
599 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
600 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}}
601 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() + 1
602 }
603
604 /// std::vector-like containers: The past-the-end iterator is invalidated.
605
vector_emplace_back(std::vector<int> & V,int n)606 void vector_emplace_back(std::vector<int> &V, int n) {
607 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
608
609 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
610 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
611
612 V.emplace_back(n);
613
614 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
615 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
616 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
617
618 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
619 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}}
620 }
621
622 /// std::deque-like containers: All iterators, including the past-the-end
623 /// iterator, are invalidated.
624
deque_emplace_back(std::deque<int> & D,int n)625 void deque_emplace_back(std::deque<int> &D, int n) {
626 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
627
628 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
629 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
630
631 D.emplace_back(n);
632
633 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
634 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
635 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
636 }
637
638 /// pop_back()
639 ///
640 /// - Design decision: shrinks containers to the <-LEFT<- (i.e. the
641 /// past-the-end position of the container is decremented).
642 ///
643 /// - Iterator invalidation rules depend the container type.
644
645 /// std::list-like containers: Iterators to the last element are invalidated.
646
list_pop_back(std::list<int> & L,int n)647 void list_pop_back(std::list<int> &L, int n) {
648 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
649
650 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
651 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
652
653 L.pop_back();
654
655 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
656 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
657 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
658
659 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
660 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() - 1
661 }
662
663 /// std::vector-like containers: Iterators to the last element, as well as the
664 /// past-the-end iterator, are invalidated.
665
vector_pop_back(std::vector<int> & V,int n)666 void vector_pop_back(std::vector<int> &V, int n) {
667 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
668
669 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
670 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
671
672 V.pop_back();
673
674 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
675 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
676 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
677
678 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
679 }
680
681 /// std::deque-like containers: Iterators to the last element are invalidated.
682 /// The past-the-end iterator is also invalidated.
683 /// Other iterators are not affected.
684
deque_pop_back(std::deque<int> & D,int n)685 void deque_pop_back(std::deque<int> &D, int n) {
686 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
687
688 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
689 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
690
691 D.pop_back();
692
693 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
694 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
695 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
696
697 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$D.begin(){{$}}}}
698 }
699
700 /// push_front()
701 ///
702 /// - Design decision: extends containers to the <-LEFT<- (i.e. the first
703 /// position of the container is decremented).
704 ///
705 /// - Iterator invalidation rules depend the container type.
706
707 /// std::list-like containers: No iterators are invalidated.
708
list_push_front(std::list<int> & L,int n)709 void list_push_front(std::list<int> &L, int n) {
710 auto i0 = L.cbegin(), i1 = L.cend();
711
712 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
713 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
714
715 L.push_front(n);
716
717 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
718 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
719
720 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
721 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}}
722 }
723
724 /// std::deque-like containers: All iterators, including the past-the-end
725 /// iterator, are invalidated.
726
deque_push_front(std::deque<int> & D,int n)727 void deque_push_front(std::deque<int> &D, int n) {
728 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
729
730 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
731 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
732
733 D.push_front(n);
734
735 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
736 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
737 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
738 }
739
740 /// std::forward_list-like containers: No iterators are invalidated.
741
forward_list_push_front(std::forward_list<int> & FL,int n)742 void forward_list_push_front(std::forward_list<int> &FL, int n) {
743 auto i0 = FL.cbegin(), i1 = FL.cend();
744
745 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
746 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
747
748 FL.push_front(n);
749
750 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
751 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
752
753 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
754 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}}
755 }
756
757 /// emplace_front()
758 ///
759 /// - Design decision: extends containers to the <-LEFT<- (i.e. the first
760 /// position of the container is decremented).
761 ///
762 /// - Iterator invalidation rules depend the container type.
763
764 /// std::list-like containers: No iterators are invalidated.
765
list_emplace_front(std::list<int> & L,int n)766 void list_emplace_front(std::list<int> &L, int n) {
767 auto i0 = L.cbegin(), i1 = L.cend();
768
769 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
770 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
771
772 L.emplace_front(n);
773
774 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
775 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
776
777 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
778 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}}
779 }
780
781 /// std::deque-like containers: All iterators, including the past-the-end
782 /// iterator, are invalidated.
783
deque_emplace_front(std::deque<int> & D,int n)784 void deque_emplace_front(std::deque<int> &D, int n) {
785 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
786
787 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
788 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
789
790 D.emplace_front(n);
791
792 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
793 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
794 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
795 }
796
797 /// std::forward_list-like containers: No iterators are invalidated.
798
forward_list_emplace_front(std::forward_list<int> & FL,int n)799 void forward_list_emplace_front(std::forward_list<int> &FL, int n) {
800 auto i0 = FL.cbegin(), i1 = FL.cend();
801
802 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
803 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
804
805 FL.emplace_front(n);
806
807 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
808 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
809
810 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
811 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}}
812 }
813
814 /// pop_front()
815 ///
816 /// - Design decision: shrinks containers to the ->RIGHT-> (i.e. the first
817 /// position of the container is incremented).
818 ///
819 /// - Iterator invalidation rules depend the container type.
820
821 /// std::list-like containers: Iterators to the first element are invalidated.
822
list_pop_front(std::list<int> & L,int n)823 void list_pop_front(std::list<int> &L, int n) {
824 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
825
826 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
827 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
828
829 L.pop_front();
830
831 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
832 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
833 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
834
835 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}}
836 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
837 }
838
839 /// std::deque-like containers: Iterators to the first element are invalidated.
840 /// Other iterators are not affected.
841
deque_pop_front(std::deque<int> & D,int n)842 void deque_pop_front(std::deque<int> &D, int n) {
843 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
844
845 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
846 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
847
848 D.pop_front();
849
850 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
851 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
852 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
853
854 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$D.begin() + 1{{$}}}}
855 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$D.end(){{$}}}}
856 }
857
858 /// std::forward_list-like containers: Iterators to the first element are
859 /// invalidated.
860
forward_list_pop_front(std::list<int> & FL,int n)861 void forward_list_pop_front(std::list<int> &FL, int n) {
862 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
863
864 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
865 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
866
867 FL.pop_front();
868
869 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
870 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
871 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
872
873 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}}
874 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
875 }
876
877 /// insert()
878 ///
879 /// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator
880 /// ahead of the insertion point are decremented; if the
881 /// relation between the insertion point and the first
882 /// position of the container is known, the first position
883 /// of the container is also decremented).
884 ///
885 /// - Iterator invalidation rules depend the container type.
886
887 /// std::list-like containers: No iterators are invalidated.
888
list_insert_begin(std::list<int> & L,int n)889 void list_insert_begin(std::list<int> &L, int n) {
890 auto i0 = L.cbegin(), i1 = L.cend();
891
892 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
893 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
894
895 auto i2 = L.insert(i0, n);
896
897 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
898 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
899
900 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
901 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1
902 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}}
903 }
904
list_insert_behind_begin(std::list<int> & L,int n)905 void list_insert_behind_begin(std::list<int> &L, int n) {
906 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
907
908 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
909 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
910
911 auto i3 = L.insert(i1, n);
912
913 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
914 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
915 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
916
917 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1
918 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}}
919 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin()
920 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
921 }
922
923 template <typename Iter> Iter return_any_iterator(const Iter &It);
924
list_insert_unknown(std::list<int> & L,int n)925 void list_insert_unknown(std::list<int> &L, int n) {
926 auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend();
927
928 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
929 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
930 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
931
932 auto i3 = L.insert(i1, n);
933
934 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
935 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
936 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
937
938 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
939 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
940 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1
941 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
942 }
943
list_insert_ahead_of_end(std::list<int> & L,int n)944 void list_insert_ahead_of_end(std::list<int> &L, int n) {
945 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
946
947 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
948 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
949
950 auto i3 = L.insert(i1, n);
951
952 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
953 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
954 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
955
956 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
957 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}}
958 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
959 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2
960 }
961
list_insert_end(std::list<int> & L,int n)962 void list_insert_end(std::list<int> &L, int n) {
963 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
964
965 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
966 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
967
968 auto i3 = L.insert(i2, n);
969
970 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
971 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
972 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
973
974 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
975 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2
976 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
977 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1
978 }
979
980 /// std::vector-like containers: Only the iterators before the insertion point
981 /// remain valid. The past-the-end iterator is also
982 /// invalidated.
983
vector_insert_begin(std::vector<int> & V,int n)984 void vector_insert_begin(std::vector<int> &V, int n) {
985 auto i0 = V.cbegin(), i1 = V.cend();
986
987 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
988 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
989
990 auto i2 = V.insert(i0, n);
991
992 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
993 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
994
995 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1
996 }
997
vector_insert_behind_begin(std::vector<int> & V,int n)998 void vector_insert_behind_begin(std::vector<int> &V, int n) {
999 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
1000
1001 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1002 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1003
1004 auto i3 = V.insert(i1, n);
1005
1006 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1007 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1008 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1009
1010 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() - 1
1011 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin()
1012 }
1013
vector_insert_unknown(std::vector<int> & V,int n)1014 void vector_insert_unknown(std::vector<int> &V, int n) {
1015 auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend();
1016
1017 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1018 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1019 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1020
1021 auto i3 = V.insert(i1, n);
1022
1023 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1024 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1025 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1026
1027 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1028 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1
1029 }
1030
vector_insert_ahead_of_end(std::vector<int> & V,int n)1031 void vector_insert_ahead_of_end(std::vector<int> &V, int n) {
1032 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
1033
1034 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1035 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1036
1037 auto i3 = V.insert(i1, n);
1038
1039 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1040 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1041 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1042
1043 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1044 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
1045 }
1046
vector_insert_end(std::vector<int> & V,int n)1047 void vector_insert_end(std::vector<int> &V, int n) {
1048 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
1049
1050 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1051 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1052
1053 auto i3 = V.insert(i2, n);
1054
1055 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1056 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1057 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1058
1059 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1060 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} FIXME: Should be $V.end() - 2
1061 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1
1062 }
1063
1064 /// std::deque-like containers: All iterators, including the past-the-end
1065 /// iterator, are invalidated.
1066
deque_insert_begin(std::deque<int> & D,int n)1067 void deque_insert_begin(std::deque<int> &D, int n) {
1068 auto i0 = D.cbegin(), i1 = D.cend();
1069
1070 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1071 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1072
1073 auto i2 = D.insert(i0, n);
1074
1075 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1076 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1077
1078 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1
1079 }
1080
deque_insert_behind_begin(std::deque<int> & D,int n)1081 void deque_insert_behind_begin(std::deque<int> &D, int n) {
1082 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
1083
1084 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1085 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1086
1087 auto i3 = D.insert(i1, n);
1088
1089 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1090 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1091 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1092
1093 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1
1094 }
1095
deque_insert_unknown(std::deque<int> & D,int n)1096 void deque_insert_unknown(std::deque<int> &D, int n) {
1097 auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend();
1098
1099 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1100 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1101 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1102
1103 auto i3 = D.insert(i1, n);
1104
1105 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1106 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1107 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1108
1109 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1
1110 }
1111
deque_insert_ahead_of_end(std::deque<int> & D,int n)1112 void deque_insert_ahead_of_end(std::deque<int> &D, int n) {
1113 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
1114
1115 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1116 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1117
1118 auto i3 = D.insert(i1, n);
1119
1120 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1121 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1122 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1123
1124 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2
1125 }
1126
deque_insert_end(std::deque<int> & D,int n)1127 void deque_insert_end(std::deque<int> &D, int n) {
1128 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
1129
1130 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1131 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1132
1133 auto i3 = D.insert(i2, n);
1134
1135 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1136 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1137 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1138
1139 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1
1140 }
1141
1142 /// insert_after() [std::forward_list-like containers]
1143 ///
1144 /// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator
1145 /// ahead of the insertion point are incremented; if the
1146 /// relation between the insertion point and the past-the-end
1147 /// position of the container is known, the first position of
1148 /// the container is also incremented).
1149 ///
1150 /// - No iterators are invalidated.
1151
forward_list_insert_after_begin(std::forward_list<int> & FL,int n)1152 void forward_list_insert_after_begin(std::forward_list<int> &FL, int n) {
1153 auto i0 = FL.cbegin(), i1 = FL.cend();
1154
1155 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1156 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1157
1158 auto i2 = FL.insert_after(i0, n);
1159
1160 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1161 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1162
1163 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1164 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1
1165 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}}
1166 }
1167
forward_list_insert_after_behind_begin(std::forward_list<int> & FL,int n)1168 void forward_list_insert_after_behind_begin(std::forward_list<int> &FL, int n) {
1169 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
1170
1171 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1172 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1173
1174 auto i3 = FL.insert_after(i1, n);
1175
1176 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1177 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1178 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1179
1180 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1181 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}}
1182 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2
1183 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
1184 }
1185
forward_list_insert_after_unknown(std::forward_list<int> & FL,int n)1186 void forward_list_insert_after_unknown(std::forward_list<int> &FL, int n) {
1187 auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = FL.cend();
1188
1189 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1190 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1191 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1192
1193 auto i3 = FL.insert_after(i1, n);
1194
1195 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1196 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1197 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1198
1199 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1200 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
1201 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
1202 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
1203 }
1204
1205 /// emplace()
1206 ///
1207 /// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator
1208 /// ahead of the emplacement point are decremented; if the
1209 /// relation between the emplacement point and the first
1210 /// position of the container is known, the first position
1211 /// of the container is also decremented).
1212 ///
1213 /// - Iterator invalidation rules depend the container type.
1214
1215 /// std::list-like containers: No iterators are invalidated.
1216
list_emplace_begin(std::list<int> & L,int n)1217 void list_emplace_begin(std::list<int> &L, int n) {
1218 auto i0 = L.cbegin(), i1 = L.cend();
1219
1220 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1221 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1222
1223 auto i2 = L.emplace(i0, n);
1224
1225 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1226 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1227
1228 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
1229 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1
1230 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}}
1231 }
1232
list_emplace_behind_begin(std::list<int> & L,int n)1233 void list_emplace_behind_begin(std::list<int> &L, int n) {
1234 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
1235
1236 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1237 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1238
1239 auto i3 = L.emplace(i1, n);
1240
1241 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1242 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1243 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1244
1245 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1
1246 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}}
1247 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin()
1248 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1249 }
1250
1251 template <typename Iter> Iter return_any_iterator(const Iter &It);
1252
list_emplace_unknown(std::list<int> & L,int n)1253 void list_emplace_unknown(std::list<int> &L, int n) {
1254 auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend();
1255
1256 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1257 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1258 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1259
1260 auto i3 = L.emplace(i1, n);
1261
1262 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1263 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1264 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1265
1266 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
1267 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
1268 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1
1269 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1270 }
1271
list_emplace_ahead_of_end(std::list<int> & L,int n)1272 void list_emplace_ahead_of_end(std::list<int> &L, int n) {
1273 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
1274
1275 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1276 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1277
1278 auto i3 = L.emplace(i1, n);
1279
1280 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1281 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1282 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1283
1284 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
1285 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}}
1286 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1287 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2
1288 }
1289
list_emplace_end(std::list<int> & L,int n)1290 void list_emplace_end(std::list<int> &L, int n) {
1291 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
1292
1293 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1294 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1295
1296 auto i3 = L.emplace(i2, n);
1297
1298 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1299 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1300 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1301
1302 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
1303 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2
1304 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1305 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1
1306 }
1307
1308 /// std::vector-like containers: Only the iterators before the emplacement point
1309 /// remain valid. The past-the-end iterator is also
1310 /// invalidated.
1311
vector_emplace_begin(std::vector<int> & V,int n)1312 void vector_emplace_begin(std::vector<int> &V, int n) {
1313 auto i0 = V.cbegin(), i1 = V.cend();
1314
1315 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1316 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1317
1318 auto i2 = V.emplace(i0, n);
1319
1320 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1321 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1322 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1
1323 }
1324
vector_emplace_behind_begin(std::vector<int> & V,int n)1325 void vector_emplace_behind_begin(std::vector<int> &V, int n) {
1326 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
1327
1328 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1329 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1330
1331 auto i3 = V.emplace(i1, n);
1332
1333 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1334 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1335 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1336
1337 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() - 1
1338 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin()
1339 }
1340
vector_emplace_unknown(std::vector<int> & V,int n)1341 void vector_emplace_unknown(std::vector<int> &V, int n) {
1342 auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend();
1343
1344 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1345 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1346 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1347
1348 auto i3 = V.emplace(i1, n);
1349
1350 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1351 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1352 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1353
1354 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1355 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1
1356 }
1357
vector_emplace_ahead_of_end(std::vector<int> & V,int n)1358 void vector_emplace_ahead_of_end(std::vector<int> &V, int n) {
1359 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
1360
1361 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1362 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1363
1364 auto i3 = V.emplace(i1, n);
1365
1366 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1367 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1368 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1369
1370 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1371 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
1372 }
1373
vector_emplace_end(std::vector<int> & V,int n)1374 void vector_emplace_end(std::vector<int> &V, int n) {
1375 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
1376
1377 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1378 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1379
1380 auto i3 = V.emplace(i2, n);
1381
1382 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1383 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1384 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1385
1386 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1387 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} FIXME: Should be $V.end() - 2
1388 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1
1389 }
1390
1391 /// std::deque-like containers: All iterators, including the past-the-end
1392 /// iterator, are invalidated.
1393
deque_emplace_begin(std::deque<int> & D,int n)1394 void deque_emplace_begin(std::deque<int> &D, int n) {
1395 auto i0 = D.cbegin(), i1 = D.cend();
1396
1397 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1398 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1399
1400 auto i2 = D.emplace(i0, n);
1401
1402 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1403 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1404 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1
1405 }
1406
deque_emplace_behind_begin(std::deque<int> & D,int n)1407 void deque_emplace_behind_begin(std::deque<int> &D, int n) {
1408 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
1409
1410 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1411 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1412
1413 auto i3 = D.emplace(i1, n);
1414
1415 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1416 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1417 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1418 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1
1419 }
1420
deque_emplace_unknown(std::deque<int> & D,int n)1421 void deque_emplace_unknown(std::deque<int> &D, int n) {
1422 auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend();
1423
1424 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1425 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1426 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1427
1428 auto i3 = D.emplace(i1, n);
1429
1430 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1431 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1432 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1433
1434 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1
1435 }
1436
deque_emplace_ahead_of_end(std::deque<int> & D,int n)1437 void deque_emplace_ahead_of_end(std::deque<int> &D, int n) {
1438 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
1439
1440 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1441 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1442
1443 auto i3 = D.emplace(i1, n);
1444
1445 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1446 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1447 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1448
1449 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2
1450 }
1451
deque_emplace_end(std::deque<int> & D,int n)1452 void deque_emplace_end(std::deque<int> &D, int n) {
1453 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
1454
1455 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1456 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1457
1458 auto i3 = D.emplace(i2, n);
1459
1460 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1461 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1462 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1463
1464 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1
1465 }
1466
1467 /// emplace_after() [std::forward_list-like containers]
1468 ///
1469 /// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator
1470 /// ahead of the emplacement point are incremented; if the
1471 /// relation between the emplacement point and the
1472 /// past-the-end position of the container is known, the
1473 /// first position of the container is also incremented).
1474 ///
1475 /// - No iterators are invalidated.
1476
forward_list_emplace_after_begin(std::forward_list<int> & FL,int n)1477 void forward_list_emplace_after_begin(std::forward_list<int> &FL, int n) {
1478 auto i0 = FL.cbegin(), i1 = FL.cend();
1479
1480 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1481 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1482
1483 auto i2 = FL.emplace_after(i0, n);
1484
1485 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1486 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1487
1488 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1489 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1
1490 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}}
1491 }
1492
forward_list_emplace_after_behind_begin(std::forward_list<int> & FL,int n)1493 void forward_list_emplace_after_behind_begin(std::forward_list<int> &FL,
1494 int n) {
1495 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
1496
1497 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1498 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1499
1500 auto i3 = FL.emplace_after(i1, n);
1501
1502 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1503 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1504 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1505
1506 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1507 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}}
1508 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2
1509 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
1510 }
1511
forward_list_emplace_after_unknown(std::forward_list<int> & FL,int n)1512 void forward_list_emplace_after_unknown(std::forward_list<int> &FL, int n) {
1513 auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = FL.cend();
1514
1515 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1516 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1517 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1518
1519 auto i3 = FL.emplace_after(i1, n);
1520
1521 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1522 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1523 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1524
1525 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1526 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
1527 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
1528 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
1529 }
1530
1531 /// erase()
1532 ///
1533 /// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator
1534 /// ahead of the ereased element are incremented; if the
1535 /// relation between the position of the erased element
1536 /// and the first position of the container is known, the
1537 /// first position of the container is also incremented).
1538 ///
1539 /// - Iterator invalidation rules depend the container type.
1540
1541 /// std::list-like containers: Iterators to the erased element are invalidated.
1542 /// Other iterators are not affected.
1543
list_erase_begin(std::list<int> & L)1544 void list_erase_begin(std::list<int> &L) {
1545 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
1546
1547 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1548 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1549
1550 auto i3 = L.erase(i0);
1551
1552 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1553 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1554 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1555
1556 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}}
1557 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 1
1558 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1559 }
1560
list_erase_behind_begin(std::list<int> & L,int n)1561 void list_erase_behind_begin(std::list<int> &L, int n) {
1562 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
1563
1564 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1565 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1566
1567 auto i3 = L.erase(i1);
1568
1569 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1570 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1571 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1572
1573 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() + 1
1574 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 2
1575 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1576 }
1577
list_erase_unknown(std::list<int> & L)1578 void list_erase_unknown(std::list<int> &L) {
1579 auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend();
1580
1581 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1582 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1583 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1584
1585 auto i3 = L.erase(i1);
1586
1587 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1588 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1589 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1590
1591 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
1592 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
1593 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1594 }
1595
list_erase_ahead_of_end(std::list<int> & L)1596 void list_erase_ahead_of_end(std::list<int> &L) {
1597 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
1598
1599 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
1600 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
1601
1602 auto i3 = L.erase(i1);
1603
1604 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1605 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1606 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1607
1608 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
1609 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
1610 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end()
1611 }
1612
1613 /// std::vector-like containers: Invalidates iterators at or after the point of
1614 /// the erase, including the past-the-end iterator.
1615
vector_erase_begin(std::vector<int> & V)1616 void vector_erase_begin(std::vector<int> &V) {
1617 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
1618
1619 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1620 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1621
1622 auto i3 = V.erase(i0);
1623
1624 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1625 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1626 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1627
1628 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 1
1629 }
1630
vector_erase_behind_begin(std::vector<int> & V,int n)1631 void vector_erase_behind_begin(std::vector<int> &V, int n) {
1632 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
1633
1634 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1635 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1636
1637 auto i3 = V.erase(i1);
1638
1639 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1640 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1641 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1642
1643 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() + 1
1644 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 2
1645 }
1646
vector_erase_unknown(std::vector<int> & V)1647 void vector_erase_unknown(std::vector<int> &V) {
1648 auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend();
1649
1650 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1651 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1652 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1653
1654 auto i3 = V.erase(i1);
1655
1656 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1657 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1658 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1659
1660 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1661 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
1662 }
1663
vector_erase_ahead_of_end(std::vector<int> & V)1664 void vector_erase_ahead_of_end(std::vector<int> &V) {
1665 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
1666
1667 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
1668 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
1669
1670 auto i3 = V.erase(i1);
1671
1672 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1673 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1674 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1675
1676 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
1677 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end()
1678 }
1679
1680 /// std::deque-like containers: All iterators are invalidated, unless the erased
1681 /// element is at the end or the beginning of the
1682 /// container, in which case only the iterators to
1683 /// the erased element are invalidated. The
1684 /// past-the-end iterator is also invalidated unless
1685 /// the erased element is at the beginning of the
1686 /// container and the last element is not erased.
1687
deque_erase_begin(std::deque<int> & D)1688 void deque_erase_begin(std::deque<int> &D) {
1689 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
1690
1691 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1692 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1693
1694 auto i3 = D.erase(i0);
1695
1696 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1697 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1698 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1699
1700 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 1
1701 }
1702
deque_erase_behind_begin(std::deque<int> & D,int n)1703 void deque_erase_behind_begin(std::deque<int> &D, int n) {
1704 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
1705
1706 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1707 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1708
1709 auto i3 = D.erase(i1);
1710
1711 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1712 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1713 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1714
1715 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 2
1716 }
1717
deque_erase_unknown(std::deque<int> & D)1718 void deque_erase_unknown(std::deque<int> &D) {
1719 auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend();
1720
1721 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1722 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1723 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1724
1725 auto i3 = D.erase(i1);
1726
1727 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1728 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1729 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1730
1731 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
1732 }
1733
deque_erase_ahead_of_end(std::deque<int> & D)1734 void deque_erase_ahead_of_end(std::deque<int> &D) {
1735 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
1736
1737 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
1738 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
1739
1740 auto i3 = D.erase(i1);
1741
1742 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
1743 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1744 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1745
1746 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end()
1747 }
1748
1749 /// erase_after() [std::forward_list-like containers]
1750 ///
1751 /// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator
1752 /// begind of the ereased element are decremented; if the
1753 /// relation between the position of the erased element
1754 /// and the past-the-end position of the container is known,
1755 /// the past-the-end position of the container is also
1756 /// decremented).
1757 ///
1758 /// - Iterators to the erased element are invalidated. Other iterators are not
1759 /// affected.
1760
1761
forward_list_erase_after_begin(std::forward_list<int> & FL)1762 void forward_list_erase_after_begin(std::forward_list<int> &FL) {
1763 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = i1, i3 = FL.cend();
1764 ++i2;
1765
1766 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1767 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1768
1769 auto i4 = FL.erase_after(i0);
1770
1771 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1772 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
1773 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
1774 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}}
1775
1776 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1777 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.begin() + 2{{$}}}} FIXME: Should be $FL.begin() + 1
1778 // clang_analyzer_express(clang_analyzer_iterator_position(i4)); FIXME: expect warning $FL.begin() + 1
1779 clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$FL.end(){{$}}}}
1780 }
1781
forward_list_erase_after_unknown(std::forward_list<int> & FL)1782 void forward_list_erase_after_unknown(std::forward_list<int> &FL) {
1783 auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = i1,
1784 i3 = i1, i4 = FL.cend();
1785 ++i2;
1786 ++i3;
1787 ++i3;
1788
1789 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
1790 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
1791 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
1792
1793 auto i5 = FL.erase_after(i1);
1794
1795 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
1796 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
1797 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
1798 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}}
1799 clang_analyzer_eval(clang_analyzer_iterator_validity(i4)); //expected-warning{{TRUE}}
1800
1801 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
1802 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
1803 clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$i1 + 2{{$}}}} FIXME: Should be $i1 + 1
1804 // clang_analyzer_express(clang_analyzer_iterator_position(i5)); FIXME: expect warning $i1 + 1
1805 clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning-re {{$FL.end(){{$}}}}
1806 }
1807
1808 struct simple_iterator_base {
1809 simple_iterator_base();
1810 simple_iterator_base(const simple_iterator_base& rhs);
1811 simple_iterator_base &operator=(const simple_iterator_base& rhs);
1812 virtual ~simple_iterator_base();
1813 bool friend operator==(const simple_iterator_base &lhs,
1814 const simple_iterator_base &rhs);
1815 bool friend operator!=(const simple_iterator_base &lhs,
1816 const simple_iterator_base &rhs);
1817 private:
1818 int *ptr;
1819 };
1820
1821 struct simple_derived_iterator: public simple_iterator_base {
1822 int& operator*();
1823 int* operator->();
1824 simple_iterator_base &operator++();
1825 simple_iterator_base operator++(int);
1826 simple_iterator_base &operator--();
1827 simple_iterator_base operator--(int);
1828 };
1829
1830 struct simple_container {
1831 typedef simple_derived_iterator iterator;
1832
1833 iterator begin();
1834 iterator end();
1835 };
1836
good_derived(simple_container c)1837 void good_derived(simple_container c) {
1838 auto i0 = c.end();
1839
1840 if (i0 != c.end()) {
1841 clang_analyzer_warnIfReached();
1842 }
1843 }
1844
iter_diff(std::vector<int> & V)1845 void iter_diff(std::vector<int> &V) {
1846 auto i0 = V.begin(), i1 = V.end();
1847 ptrdiff_t len = i1 - i0; // no-crash
1848 }
1849
deferred_assumption(std::vector<int> & V,int e)1850 void deferred_assumption(std::vector<int> &V, int e) {
1851 const auto first = V.begin();
1852 const auto comp1 = (first != V.end()), comp2 = (first == V.end());
1853 if (comp1) {
1854 clang_analyzer_eval(clang_analyzer_container_end(V) ==
1855 clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}}
1856 }
1857 }
1858
loop(std::vector<int> & V,int e)1859 void loop(std::vector<int> &V, int e) {
1860 auto start = V.begin();
1861 while (true) {
1862 auto item = std::find(start, V.end(), e);
1863 if (item == V.end())
1864 break;
1865
1866 clang_analyzer_eval(clang_analyzer_container_end(V) ==
1867 clang_analyzer_iterator_position(item)); // expected-warning@-1{{FALSE}}
1868 }
1869 }
1870
1871 template <typename InputIterator, typename T>
nonStdFind(InputIterator first,InputIterator last,const T & val)1872 InputIterator nonStdFind(InputIterator first, InputIterator last,
1873 const T &val) {
1874 for (auto i = first; i != last; ++i) {
1875 if (*i == val) {
1876 return i;
1877 }
1878 }
1879 return last;
1880 }
1881
non_std_find(std::vector<int> & V,int e)1882 void non_std_find(std::vector<int> &V, int e) {
1883 auto first = nonStdFind(V.begin(), V.end(), e);
1884 clang_analyzer_eval(clang_analyzer_container_end(V) ==
1885 clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} expected-warning@-1{{TRUE}}
1886 if (V.end() != first) {
1887 clang_analyzer_eval(clang_analyzer_container_end(V) ==
1888 clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}}
1889 }
1890 }
1891
1892 template<typename T>
1893 struct cont_with_ptr_iterator {
1894 typedef T* iterator;
1895 T* begin() const;
1896 T* end() const;
1897 };
1898
begin_ptr_iterator(const cont_with_ptr_iterator<int> & c)1899 void begin_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1900 auto i = c.begin();
1901
1902 clang_analyzer_eval(clang_analyzer_iterator_container(i) == &c); // expected-warning{{TRUE}}
1903 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
1904 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin()}}
1905
1906 if (i != c.begin()) {
1907 clang_analyzer_warnIfReached();
1908 }
1909 }
1910
prefix_increment_ptr_iterator(const cont_with_ptr_iterator<int> & c)1911 void prefix_increment_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1912 auto i = c.begin();
1913
1914 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
1915
1916 auto j = ++i;
1917
1918 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 1}}
1919 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.begin() + 1}}
1920 }
1921
prefix_decrement_ptr_iterator(const cont_with_ptr_iterator<int> & c)1922 void prefix_decrement_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1923 auto i = c.end();
1924
1925 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()");
1926
1927 auto j = --i;
1928
1929 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 1}}
1930 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.end() - 1}}
1931 }
1932
postfix_increment_ptr_iterator(const cont_with_ptr_iterator<int> & c)1933 void postfix_increment_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1934 auto i = c.begin();
1935
1936 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
1937
1938 auto j = i++;
1939
1940 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 1}}
1941 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.begin()}}
1942 }
1943
postfix_decrement_ptr_iterator(const cont_with_ptr_iterator<int> & c)1944 void postfix_decrement_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1945 auto i = c.end();
1946
1947 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()");
1948
1949 auto j = i--;
1950
1951 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 1}}
1952 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.end()}}
1953 }
1954
plus_equal_ptr_iterator(const cont_with_ptr_iterator<int> & c)1955 void plus_equal_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1956 auto i = c.begin();
1957
1958 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
1959
1960 i += 2;
1961
1962 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 2}}
1963 }
1964
minus_equal_ptr_iterator(const cont_with_ptr_iterator<int> & c)1965 void minus_equal_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1966 auto i = c.end();
1967
1968 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()");
1969
1970 i -= 2;
1971
1972 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 2}}
1973 }
1974
minus_equal_ptr_iterator_variable(const cont_with_ptr_iterator<int> & c,int n)1975 void minus_equal_ptr_iterator_variable(const cont_with_ptr_iterator<int> &c,
1976 int n) {
1977 auto i = c.end();
1978
1979 i -= n; // no-crash
1980 }
1981
plus_lhs_ptr_iterator(const cont_with_ptr_iterator<int> & c)1982 void plus_lhs_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1983 auto i1 = c.begin();
1984
1985 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
1986
1987 auto i2 = i1 + 2;
1988
1989 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}}
1990 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.begin()}}
1991 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.begin() + 2}}
1992 }
1993
plus_rhs_ptr_iterator(const cont_with_ptr_iterator<int> & c)1994 void plus_rhs_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
1995 auto i1 = c.begin();
1996
1997 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
1998
1999 auto i2 = 2 + i1;
2000
2001 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}}
2002 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.begin()}}
2003 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.begin() + 2}}
2004 }
2005
minus_ptr_iterator(const cont_with_ptr_iterator<int> & c)2006 void minus_ptr_iterator(const cont_with_ptr_iterator<int> &c) {
2007 auto i1 = c.end();
2008
2009 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()");
2010
2011 auto i2 = i1 - 2;
2012
2013 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}}
2014 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.end()}}
2015 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.end() - 2}}
2016 }
2017
ptr_iter_diff(cont_with_ptr_iterator<int> & c)2018 void ptr_iter_diff(cont_with_ptr_iterator<int> &c) {
2019 auto i0 = c.begin(), i1 = c.end();
2020 ptrdiff_t len = i1 - i0; // no-crash
2021 }
2022
ptr_iter_cmp_nullptr(cont_with_ptr_iterator<int> & c)2023 void ptr_iter_cmp_nullptr(cont_with_ptr_iterator<int> &c) {
2024 auto i0 = c.begin();
2025 if (i0 != nullptr) // no-crash
2026 ++i0;
2027 }
2028
2029 void clang_analyzer_printState();
2030
print_state(std::vector<int> & V)2031 void print_state(std::vector<int> &V) {
2032 const auto i0 = V.cbegin();
2033 clang_analyzer_printState();
2034
2035 // CHECK: "checker_messages": [
2036 // CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [
2037 // CHECK-NEXT: "Iterator Positions :",
2038 // CHECK-NEXT: "i0 : Valid ; Container == SymRegion{reg_$[[#]]<std::vector<int> & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}"
2039 // CHECK-NEXT: ]}
2040
2041 *i0;
2042 const auto i1 = V.cend();
2043 clang_analyzer_printState();
2044
2045 // CHECK: "checker_messages": [
2046 // CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [
2047 // CHECK-NEXT: "Iterator Positions :",
2048 // CHECK-NEXT: "i1 : Valid ; Container == SymRegion{reg_$[[#]]<std::vector<int> & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}"
2049 // CHECK-NEXT: ]}
2050
2051 *i1;
2052 }
2053