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