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