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