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