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