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