xref: /llvm-project/clang/test/Analysis/iterator-range.cpp (revision bcc662484a95c95f7d193e6a791fc5d1c4a2c74f)
1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false -analyzer-output=text %s -verify
2 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorRange -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -analyzer-output=text %s -verify
3 
4 #include "Inputs/system-header-simulator-cxx.h"
5 
6 void clang_analyzer_warnIfReached();
7 
8 // Dereference - operator*()
9 
10 void deref_begin(const std::vector<int> &V) {
11   auto i = V.begin();
12   *i; // no-warning
13 }
14 
15 void deref_begind_begin(const std::vector<int> &V) {
16   auto i = ++V.begin();
17   *i; // no-warning
18 }
19 
20 template <typename Iter> Iter return_any_iterator(const Iter &It);
21 
22 void deref_unknown(const std::vector<int> &V) {
23   auto i = return_any_iterator(V.begin());
24   *i; // no-warning
25 }
26 
27 void deref_ahead_of_end(const std::vector<int> &V) {
28   auto i = --V.end();
29   *i; // no-warning
30 }
31 
32 void deref_end(const std::vector<int> &V) {
33   auto i = V.end();
34   *i; // expected-warning{{Past-the-end iterator dereferenced}}
35       // expected-note@-1{{Past-the-end iterator dereferenced}}
36 }
37 
38 // Prefix increment - operator++()
39 
40 void incr_begin(const std::vector<int> &V) {
41   auto i = V.begin();
42   ++i; // no-warning
43 }
44 
45 void incr_behind_begin(const std::vector<int> &V) {
46   auto i = ++V.begin();
47   ++i; // no-warning
48 }
49 
50 void incr_unknown(const std::vector<int> &V) {
51   auto i = return_any_iterator(V.begin());
52   ++i; // no-warning
53 }
54 
55 void incr_ahead_of_end(const std::vector<int> &V) {
56   auto i = --V.end();
57   ++i; // no-warning
58 }
59 
60 void incr_end(const std::vector<int> &V) {
61   auto i = V.end();
62   ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
63        // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
64 }
65 
66 // Postfix increment - operator++(int)
67 
68 void begin_incr(const std::vector<int> &V) {
69   auto i = V.begin();
70   i++; // no-warning
71 }
72 
73 void behind_begin_incr(const std::vector<int> &V) {
74   auto i = ++V.begin();
75   i++; // no-warning
76 }
77 
78 void unknown_incr(const std::vector<int> &V) {
79   auto i = return_any_iterator(V.begin());
80   i++; // no-warning
81 }
82 
83 void ahead_of_end_incr(const std::vector<int> &V) {
84   auto i = --V.end();
85   i++; // no-warning
86 }
87 
88 void end_incr(const std::vector<int> &V) {
89   auto i = V.end();
90   i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
91        // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
92 }
93 
94 // Prefix decrement - operator--()
95 
96 void decr_begin(const std::vector<int> &V) {
97   auto i = V.begin();
98   --i; // expected-warning{{Iterator decremented ahead of its valid range}}
99        // expected-note@-1{{Iterator decremented ahead of its valid range}}
100 }
101 
102 void decr_behind_begin(const std::vector<int> &V) {
103   auto i = ++V.begin();
104   --i; // no-warning
105 }
106 
107 void decr_unknown(const std::vector<int> &V) {
108   auto i = return_any_iterator(V.begin());
109   --i; // no-warning
110 }
111 
112 void decr_ahead_of_end(const std::vector<int> &V) {
113   auto i = --V.end();
114   --i; // no-warning
115 }
116 
117 void decr_end(const std::vector<int> &V) {
118   auto i = V.end();
119   --i; // no-warning
120 }
121 
122 // Postfix decrement - operator--(int)
123 
124 void begin_decr(const std::vector<int> &V) {
125   auto i = V.begin();
126   i--; // expected-warning{{Iterator decremented ahead of its valid range}}
127        // expected-note@-1{{Iterator decremented ahead of its valid range}}
128 }
129 
130 void behind_begin_decr(const std::vector<int> &V) {
131   auto i = ++V.begin();
132   i--; // no-warning
133 }
134 
135 void unknown_decr(const std::vector<int> &V) {
136   auto i = return_any_iterator(V.begin());
137   i--; // no-warning
138 }
139 
140 void ahead_of_end_decr(const std::vector<int> &V) {
141   auto i = --V.end();
142   i--; // no-warning
143 }
144 
145 void end_decr(const std::vector<int> &V) {
146   auto i = V.end();
147   i--; // no-warning
148 }
149 
150 // Addition assignment - operator+=(int)
151 
152 void incr_by_2_begin(const std::vector<int> &V) {
153   auto i = V.begin();
154   i += 2; // no-warning
155 }
156 
157 void incr_by_2_behind_begin(const std::vector<int> &V) {
158   auto i = ++V.begin();
159   i += 2; // no-warning
160 }
161 
162 void incr_by_2_unknown(const std::vector<int> &V) {
163   auto i = return_any_iterator(V.begin());
164   i += 2; // no-warning
165 }
166 
167 void incr_by_2_ahead_by_2_of_end(const std::vector<int> &V) {
168   auto i = --V.end();
169   --i;
170   i += 2; // no-warning
171 }
172 
173 void incr_by_2_ahead_of_end(const std::vector<int> &V) {
174   auto i = --V.end();
175   i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
176           // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
177 }
178 
179 void incr_by_2_end(const std::vector<int> &V) {
180   auto i = V.end();
181   i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
182           // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
183 }
184 
185 // Addition - operator+(int)
186 
187 void incr_by_2_copy_begin(const std::vector<int> &V) {
188   auto i = V.begin();
189   auto j = i + 2; // no-warning
190 }
191 
192 void incr_by_2_copy_behind_begin(const std::vector<int> &V) {
193   auto i = ++V.begin();
194   auto j = i + 2; // no-warning
195 }
196 
197 void incr_by_2_copy_unknown(const std::vector<int> &V) {
198   auto i = return_any_iterator(V.begin());
199   auto j = i + 2; // no-warning
200 }
201 
202 void incr_by_2_copy_ahead_by_2_of_end(const std::vector<int> &V) {
203   auto i = --V.end();
204   --i;
205   auto j = i + 2; // no-warning
206 }
207 
208 void incr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
209   auto i = --V.end();
210   auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
211                   // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
212 }
213 
214 void incr_by_2_copy_end(const std::vector<int> &V) {
215   auto i = V.end();
216   auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
217                   // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
218 }
219 
220 // Subtraction assignment - operator-=(int)
221 
222 void decr_by_2_begin(const std::vector<int> &V) {
223   auto i = V.begin();
224   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
225           // expected-note@-1{{Iterator decremented ahead of its valid range}}
226 }
227 
228 void decr_by_2_behind_begin(const std::vector<int> &V) {
229   auto i = ++V.begin();
230   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
231           // expected-note@-1{{Iterator decremented ahead of its valid range}}
232 }
233 
234 void decr_by_2_behind_begin_by_2(const std::vector<int> &V) {
235   auto i = ++V.begin();
236   ++i;
237   i -= 2; // no-warning
238 }
239 
240 void decr_by_2_unknown(const std::vector<int> &V) {
241   auto i = return_any_iterator(V.begin());
242   i -= 2; // no-warning
243 }
244 
245 void decr_by_2_ahead_of_end(const std::vector<int> &V) {
246   auto i = --V.end();
247   i -= 2; // no-warning
248 }
249 
250 void decr_by_2_end(const std::vector<int> &V) {
251   auto i = V.end();
252   i -= 2; // no-warning
253 }
254 
255 // Subtraction - operator-(int)
256 
257 void decr_by_2_copy_begin(const std::vector<int> &V) {
258   auto i = V.begin();
259   auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
260                   // expected-note@-1{{Iterator decremented ahead of its valid range}}
261 }
262 
263 void decr_by_2_copy_behind_begin(const std::vector<int> &V) {
264   auto i = ++V.begin();
265   auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
266                   // expected-note@-1{{Iterator decremented ahead of its valid range}}
267 }
268 
269 void decr_by_2_copy_behind_begin_by_2(const std::vector<int> &V) {
270   auto i = ++V.begin();
271   ++i;
272   auto j = i - 2; // no-warning
273 }
274 
275 void decr_by_2_copy_unknown(const std::vector<int> &V) {
276   auto i = return_any_iterator(V.begin());
277   auto j = i - 2; // no-warning
278 }
279 
280 void decr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
281   auto i = --V.end();
282   auto j = i - 2; // no-warning
283 }
284 
285 void decr_by_2_copy_end(const std::vector<int> &V) {
286   auto i = V.end();
287   auto j = i - 2; // no-warning
288 }
289 
290 //
291 // Subscript - operator[](int)
292 //
293 
294 // By zero
295 
296 void subscript_zero_begin(const std::vector<int> &V) {
297   auto i = V.begin();
298   auto j = i[0]; // no-warning
299 }
300 
301 void subscript_zero_behind_begin(const std::vector<int> &V) {
302   auto i = ++V.begin();
303   auto j = i[0]; // no-warning
304 }
305 
306 void subscript_zero_unknown(const std::vector<int> &V) {
307   auto i = return_any_iterator(V.begin());
308   auto j = i[0]; // no-warning
309 }
310 
311 void subscript_zero_ahead_of_end(const std::vector<int> &V) {
312   auto i = --V.end();
313   auto j = i[0]; // no-warning
314 }
315 
316 void subscript_zero_end(const std::vector<int> &V) {
317   auto i = V.end();
318   auto j = i[0]; // expected-warning{{Past-the-end iterator dereferenced}}
319                  // expected-note@-1{{Past-the-end iterator dereferenced}}
320 }
321 
322 // By negative number
323 
324 void subscript_negative_begin(const std::vector<int> &V) {
325   auto i = V.begin();
326   auto j = i[-1]; // no-warning FIXME: expect warning Iterator decremented ahead of its valid range
327 }
328 
329 void subscript_negative_behind_begin(const std::vector<int> &V) {
330   auto i = ++V.begin();
331   auto j = i[-1]; // no-warning
332 }
333 
334 void subscript_negative_unknown(const std::vector<int> &V) {
335   auto i = return_any_iterator(V.begin());
336   auto j = i[-1]; // no-warning
337 }
338 
339 void subscript_negative_ahead_of_end(const std::vector<int> &V) {
340   auto i = --V.end();
341   auto j = i[-1]; // no-warning
342 }
343 
344 void subscript_negative_end(const std::vector<int> &V) {
345   auto i = V.end();
346   auto j = i[-1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect no warning
347                   // expected-note@-1{{Past-the-end iterator dereferenced}}
348 }
349 
350 // By positive number
351 
352 void subscript_positive_begin(const std::vector<int> &V) {
353   auto i = V.begin();
354   auto j = i[1]; // no-warning
355 }
356 
357 void subscript_positive_behind_begin(const std::vector<int> &V) {
358   auto i = ++V.begin();
359   auto j = i[1]; // no-warning
360 }
361 
362 void subscript_positive_unknown(const std::vector<int> &V) {
363   auto i = return_any_iterator(V.begin());
364   auto j = i[1]; // no-warning
365 }
366 
367 void subscript_positive_ahead_of_end(const std::vector<int> &V) {
368   auto i = --V.end();
369   auto j = i[1]; // no-warning FIXME: expected warning Past-the-end iterator dereferenced
370 }
371 
372 void subscript_positive_end(const std::vector<int> &V) {
373   auto i = V.end();
374   auto j = i[1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect warning Iterator incremented behind the past-the-end iterator
375                  // expected-note@-1{{Past-the-end iterator dereferenced}} FIXME: expect note@-1 Iterator incremented behind the past-the-end iterator
376 }
377 
378 //
379 // std::advance()
380 //
381 
382 // std::advance() by +1
383 
384 void advance_plus_1_begin(const std::vector<int> &V) {
385   auto i = V.begin();
386   std::advance(i, 1); // no-warning
387 }
388 
389 void advance_plus_1_behind_begin(const std::vector<int> &V) {
390   auto i = ++V.begin();
391   std::advance(i, 1); // no-warning
392 }
393 
394 void advance_plus_1_unknown(const std::vector<int> &V) {
395   auto i = return_any_iterator(V.begin());
396   std::advance(i, 1); // no-warning
397 }
398 
399 void advance_plus_1_ahead_of_end(const std::vector<int> &V) {
400   auto i = --V.end();
401   std::advance(i, 1); // no-warning
402 }
403 
404 void advance_plus_1_end(const std::vector<int> &V) {
405   auto i = V.end();
406   std::advance(i, 1); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
407                       // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
408 }
409 
410 // std::advance() by -1
411 
412 void advance_minus_1_begin(const std::vector<int> &V) {
413   auto i = V.begin();
414   std::advance(i, -1); // expected-warning{{Iterator decremented ahead of its valid range}}
415                        // expected-note@-1{{Iterator decremented ahead of its valid range}}
416 }
417 
418 void advance_minus_1_behind_begin(const std::vector<int> &V) {
419   auto i = ++V.begin();
420   std::advance(i, -1); // no-warning
421 }
422 
423 void advance_minus_1_unknown(const std::vector<int> &V) {
424   auto i = return_any_iterator(V.begin());
425   std::advance(i, -1); // no-warning
426 }
427 
428 void advance_minus_1_ahead_of_end(const std::vector<int> &V) {
429   auto i = --V.end();
430   std::advance(i, -1); // no-warning
431 }
432 
433 void advance_minus_1_end(const std::vector<int> &V) {
434   auto i = V.end();
435   std::advance(i, -1); // no-warning
436 }
437 
438 // std::advance() by +2
439 
440 void advance_plus_2_begin(const std::vector<int> &V) {
441   auto i = V.begin();
442   std::advance(i, 2); // no-warning
443 }
444 
445 void advance_plus_2_behind_begin(const std::vector<int> &V) {
446   auto i = ++V.begin();
447   std::advance(i, 2); // no-warning
448 }
449 
450 void advance_plus_2_unknown(const std::vector<int> &V) {
451   auto i = return_any_iterator(V.begin());
452   std::advance(i, 2); // no-warning
453 }
454 
455 void advance_plus_2_ahead_of_end(const std::vector<int> &V) {
456   auto i = --V.end();
457   std::advance(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
458                       // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
459 }
460 
461 void advance_plus_2_end(const std::vector<int> &V) {
462   auto i = V.end();
463   std::advance(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
464                       // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
465 }
466 
467 // std::advance() by -2
468 
469 void advance_minus_2_begin(const std::vector<int> &V) {
470   auto i = V.begin();
471   std::advance(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
472                        // expected-note@-1{{Iterator decremented ahead of its valid range}}
473 }
474 
475 void advance_minus_2_behind_begin(const std::vector<int> &V) {
476   auto i = ++V.begin();
477   std::advance(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
478                        // expected-note@-1{{Iterator decremented ahead of its valid range}}
479 }
480 
481 void advance_minus_2_unknown(const std::vector<int> &V) {
482   auto i = return_any_iterator(V.begin());
483   std::advance(i, -2); // no-warning
484 }
485 
486 void advance_minus_2_ahead_of_end(const std::vector<int> &V) {
487   auto i = --V.end();
488   std::advance(i, -2); // no-warning
489 }
490 
491 void advance_minus_2_end(const std::vector<int> &V) {
492   auto i = V.end();
493   std::advance(i, -2); // no-warning
494 }
495 
496 // std::advance() by 0
497 
498 void advance_0_begin(const std::vector<int> &V) {
499   auto i = V.begin();
500   std::advance(i, 0); // no-warning
501 }
502 
503 void advance_0_behind_begin(const std::vector<int> &V) {
504   auto i = ++V.begin();
505   std::advance(i, 0); // no-warning
506 }
507 
508 void advance_0_unknown(const std::vector<int> &V) {
509   auto i = return_any_iterator(V.begin());
510   std::advance(i, 0); // no-warning
511 }
512 
513 void advance_0_ahead_of_end(const std::vector<int> &V) {
514   auto i = --V.end();
515   std::advance(i, 0); // no-warning
516 }
517 
518 void advance_0_end(const std::vector<int> &V) {
519   auto i = V.end();
520   std::advance(i, 0); // no-warning
521 }
522 
523 //
524 // std::next()
525 //
526 
527 // std::next() by +1 (default)
528 
529 void next_plus_1_begin(const std::vector<int> &V) {
530   auto i = V.begin();
531   auto j = std::next(i); // no-warning
532 }
533 
534 void next_plus_1_behind_begin(const std::vector<int> &V) {
535   auto i = ++V.begin();
536   auto j = std::next(i); // no-warning
537 }
538 
539 void next_plus_1_unknown(const std::vector<int> &V) {
540   auto i = return_any_iterator(V.begin());
541   auto j = std::next(i); // no-warning
542 }
543 
544 void next_plus_1_ahead_of_end(const std::vector<int> &V) {
545   auto i = --V.end();
546   auto j = std::next(i); // no-warning
547 }
548 
549 void next_plus_1_end(const std::vector<int> &V) {
550   auto i = V.end();
551   auto j = std::next(i); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
552                          // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
553 }
554 
555 // std::next() by -1
556 
557 void next_minus_1_begin(const std::vector<int> &V) {
558   auto i = V.begin();
559   auto j = std::next(i, -1); // expected-warning{{Iterator decremented ahead of its valid range}}
560                              // expected-note@-1{{Iterator decremented ahead of its valid range}}
561 }
562 
563 void next_minus_1_behind_begin(const std::vector<int> &V) {
564   auto i = ++V.begin();
565   auto j = std::next(i, -1); // no-warning
566 }
567 
568 void next_minus_1_unknown(const std::vector<int> &V) {
569   auto i = return_any_iterator(V.begin());
570   auto j = std::next(i, -1); // no-warning
571 }
572 
573 void next_minus_1_ahead_of_end(const std::vector<int> &V) {
574   auto i = --V.end();
575   auto j = std::next(i, -1); // no-warning
576 }
577 
578 void next_minus_1_end(const std::vector<int> &V) {
579   auto i = V.end();
580   auto j = std::next(i, -1); // no-warning
581 }
582 
583 // std::next() by +2
584 
585 void next_plus_2_begin(const std::vector<int> &V) {
586   auto i = V.begin();
587   auto j = std::next(i, 2); // no-warning
588 }
589 
590 void next_plus_2_behind_begin(const std::vector<int> &V) {
591   auto i = ++V.begin();
592   auto j = std::next(i, 2); // no-warning
593 }
594 
595 void next_plus_2_unknown(const std::vector<int> &V) {
596   auto i = return_any_iterator(V.begin());
597   auto j = std::next(i, 2); // no-warning
598 }
599 
600 void next_plus_2_ahead_of_end(const std::vector<int> &V) {
601   auto i = --V.end();
602   auto j = std::next(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
603                             // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
604 }
605 
606 void next_plus_2_end(const std::vector<int> &V) {
607   auto i = V.end();
608   auto j = std::next(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
609                             // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
610 }
611 
612 // std::next() by -2
613 
614 void next_minus_2_begin(const std::vector<int> &V) {
615   auto i = V.begin();
616   auto j = std::next(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
617                              // expected-note@-1{{Iterator decremented ahead of its valid range}}
618 }
619 
620 void next_minus_2_behind_begin(const std::vector<int> &V) {
621   auto i = ++V.begin();
622   auto j = std::next(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
623                              // expected-note@-1{{Iterator decremented ahead of its valid range}}
624 }
625 
626 void next_minus_2_unknown(const std::vector<int> &V) {
627   auto i = return_any_iterator(V.begin());
628   auto j = std::next(i, -2); // no-warning
629 }
630 
631 void next_minus_2_ahead_of_end(const std::vector<int> &V) {
632   auto i = --V.end();
633   auto j = std::next(i, -2); // no-warning
634 }
635 
636 void next_minus_2_end(const std::vector<int> &V) {
637   auto i = V.end();
638   auto j = std::next(i, -2); // no-warning
639 }
640 
641 // std::next() by 0
642 
643 void next_0_begin(const std::vector<int> &V) {
644   auto i = V.begin();
645   auto j = std::next(i, 0); // no-warning
646 }
647 
648 void next_0_behind_begin(const std::vector<int> &V) {
649   auto i = ++V.begin();
650   auto j = std::next(i, 0); // no-warning
651 }
652 
653 void next_0_unknown(const std::vector<int> &V) {
654   auto i = return_any_iterator(V.begin());
655   auto j = std::next(i, 0); // no-warning
656 }
657 
658 void next_0_ahead_of_end(const std::vector<int> &V) {
659   auto i = --V.end();
660   auto j = std::next(i, 0); // no-warning
661 }
662 
663 void next_0_end(const std::vector<int> &V) {
664   auto i = V.end();
665   auto j = std::next(i, 0); // no-warning
666 }
667 
668 //
669 // std::prev()
670 //
671 
672 // std::prev() by +1 (default)
673 
674 void prev_plus_1_begin(const std::vector<int> &V) {
675   auto i = V.begin();
676   auto j = std::prev(i); // expected-warning{{Iterator decremented ahead of its valid range}}
677                          // expected-note@-1{{Iterator decremented ahead of its valid range}}
678 }
679 
680 void prev_plus_1_behind_begin(const std::vector<int> &V) {
681   auto i = ++V.begin();
682   auto j = std::prev(i); // no-warning
683 }
684 
685 void prev_plus_1_unknown(const std::vector<int> &V) {
686   auto i = return_any_iterator(V.begin());
687   auto j = std::prev(i); // no-warning
688 }
689 
690 void prev_plus_1_ahead_of_end(const std::vector<int> &V) {
691   auto i = --V.end();
692   auto j = std::prev(i); // no-warning
693 }
694 
695 void prev_plus_1_end(const std::vector<int> &V) {
696   auto i = V.end();
697   auto j = std::prev(i); // no-warning
698 }
699 
700 // std::prev() by -1
701 
702 void prev_minus_1_begin(const std::vector<int> &V) {
703   auto i = V.begin();
704   auto j = std::prev(i, -1); // no-warning
705 }
706 
707 void prev_minus_1_behind_begin(const std::vector<int> &V) {
708   auto i = ++V.begin();
709   auto j = std::prev(i, -1); // no-warning
710 }
711 
712 void prev_minus_1_unknown(const std::vector<int> &V) {
713   auto i = return_any_iterator(V.begin());
714   auto j = std::prev(i, -1); // no-warning
715 }
716 
717 void prev_minus_1_ahead_of_end(const std::vector<int> &V) {
718   auto i = --V.end();
719   auto j = std::prev(i, -1); // no-warning
720 }
721 
722 void prev_minus_1_end(const std::vector<int> &V) {
723   auto i = V.end();
724   auto j = std::prev(i, -1); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
725                              // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
726 }
727 
728 // std::prev() by +2
729 
730 void prev_plus_2_begin(const std::vector<int> &V) {
731   auto i = V.begin();
732   auto j = std::prev(i, 2); // expected-warning{{Iterator decremented ahead of its valid range}}
733                             // expected-note@-1{{Iterator decremented ahead of its valid range}}
734 }
735 
736 void prev_plus_2_behind_begin(const std::vector<int> &V) {
737   auto i = ++V.begin();
738   auto j = std::prev(i, 2); // expected-warning{{Iterator decremented ahead of its valid range}}
739                             // expected-note@-1{{Iterator decremented ahead of its valid range}}
740 }
741 
742 void prev_plus_2_unknown(const std::vector<int> &V) {
743   auto i = return_any_iterator(V.begin());
744   auto j = std::prev(i, 2); // no-warning
745 }
746 
747 void prev_plus_2_ahead_of_end(const std::vector<int> &V) {
748   auto i = --V.end();
749   auto j = std::prev(i, 2); // no-warning
750 }
751 
752 void prev_plus_2_end(const std::vector<int> &V) {
753   auto i = V.end();
754   auto j = std::prev(i, 2); // no-warning
755 }
756 
757 // std::prev() by -2
758 
759 void prev_minus_2_begin(const std::vector<int> &V) {
760   auto i = V.begin();
761   auto j = std::prev(i, -2); // no-warning
762 }
763 
764 void prev_minus_2_behind_begin(const std::vector<int> &V) {
765   auto i = ++V.begin();
766   auto j = std::prev(i, -2); // no-warning
767 }
768 
769 void prev_minus_2_unknown(const std::vector<int> &V) {
770   auto i = return_any_iterator(V.begin());
771   auto j = std::prev(i, -2); // no-warning
772 }
773 
774 void prev_minus_2_ahead_of_end(const std::vector<int> &V) {
775   auto i = --V.end();
776   auto j = std::prev(i, -2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
777                              // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
778 }
779 
780 void prev_minus_2_end(const std::vector<int> &V) {
781   auto i = V.end();
782   auto j = std::prev(i, -2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
783                              // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
784 }
785 
786 // std::prev() by 0
787 
788 void prev_0_begin(const std::vector<int> &V) {
789   auto i = V.begin();
790   auto j = std::prev(i, 0); // no-warning
791 }
792 
793 void prev_0_behind_begin(const std::vector<int> &V) {
794   auto i = ++V.begin();
795   auto j = std::prev(i, 0); // no-warning
796 }
797 
798 void prev_0_unknown(const std::vector<int> &V) {
799   auto i = return_any_iterator(V.begin());
800   auto j = std::prev(i, 0); // no-warning
801 }
802 
803 void prev_0_ahead_of_end(const std::vector<int> &V) {
804   auto i = --V.end();
805   auto j = std::prev(i, 0); // no-warning
806 }
807 
808 void prev_0_end(const std::vector<int> &V) {
809   auto i = V.end();
810   auto j = std::prev(i, 0); // no-warning
811 }
812 
813 // std::prev() with int* for checking Loc value argument
814 namespace std {
815 template <typename T>
816 T prev(T, int *);
817 }
818 
819 void prev_loc_value(const std::vector<int> &V, int o) {
820 
821   auto i = return_any_iterator(V.begin());
822   int *offset = &o;
823   auto j = std::prev(i, offset); // no-warning
824 }
825 
826 //
827 // Structure member dereference operators
828 //
829 
830 struct S {
831   int n;
832 };
833 
834 // Member dereference - operator->()
835 
836 void arrow_deref_begin(const std::vector<S> &V) {
837   auto i = V.begin();
838   int n = i->n; // no-warning
839 }
840 
841 void arrow_deref_end(const std::vector<S> &V) {
842   auto i = V.end();
843   int n = i->n; // expected-warning{{Past-the-end iterator dereferenced}}
844                 // expected-note@-1{{Past-the-end iterator dereferenced}}
845 }
846 
847 // Container modification - test path notes
848 
849 void deref_end_after_pop_back(std::vector<int> &V) {
850   const auto i = --V.end();
851 
852   V.pop_back(); // expected-note{{Container 'V' shrank from the back by 1 position}}
853 
854   *i; // expected-warning{{Past-the-end iterator dereferenced}}
855       // expected-note@-1{{Past-the-end iterator dereferenced}}
856 }
857 
858 template<typename T>
859 struct cont_with_ptr_iterator {
860   T* begin() const;
861   T* end() const;
862 };
863 
864 void deref_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
865   auto i = c.end();
866   (void) *i; // expected-warning{{Past-the-end iterator dereferenced}}
867              // expected-note@-1{{Past-the-end iterator dereferenced}}
868 }
869 
870 void array_deref_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
871   auto i = c.end();
872   (void) i[0]; // expected-warning{{Past-the-end iterator dereferenced}}
873                // expected-note@-1{{Past-the-end iterator dereferenced}}
874 }
875 
876 void arrow_deref_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
877   auto i = c.end();
878   (void) i->n; // expected-warning{{Past-the-end iterator dereferenced}}
879                // expected-note@-1{{Past-the-end iterator dereferenced}}
880 }
881 
882 void arrow_star_deref_end_ptr_iterator(const cont_with_ptr_iterator<S> &c,
883                                        int S::*p) {
884   auto i = c.end();
885   (void)(i->*p); // expected-warning{{Past-the-end iterator dereferenced}}
886                  // expected-note@-1{{Past-the-end iterator dereferenced}}
887 }
888 
889 void prefix_incr_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
890   auto i = c.end();
891   ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
892        // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
893 }
894 
895 void postfix_incr_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
896   auto i = c.end();
897   i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
898        // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
899 }
900 
901 void prefix_decr_begin_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
902   auto i = c.begin();
903   --i; // expected-warning{{Iterator decremented ahead of its valid range}}
904        // expected-note@-1{{Iterator decremented ahead of its valid range}}
905 }
906 
907 void postfix_decr_begin_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
908   auto i = c.begin();
909   i--; // expected-warning{{Iterator decremented ahead of its valid range}}
910        // expected-note@-1{{Iterator decremented ahead of its valid range}}
911 }
912 
913 void prefix_add_2_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
914   auto i = c.end();
915   (void)(i + 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
916                  // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
917 }
918 
919 void postfix_add_assign_2_end_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
920   auto i = c.end();
921   i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
922           // expected-note@-1{{Iterator incremented behind the past-the-end iterator}}
923 }
924 
925 void prefix_minus_2_begin_ptr_iterator(const cont_with_ptr_iterator<S> &c) {
926   auto i = c.begin();
927   (void)(i - 2); // expected-warning{{Iterator decremented ahead of its valid range}}
928                  // expected-note@-1{{Iterator decremented ahead of its valid range}}
929 }
930 
931 void postfix_minus_assign_2_begin_ptr_iterator(
932     const cont_with_ptr_iterator<S> &c) {
933   auto i = c.begin();
934   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
935           // expected-note@-1{{Iterator decremented ahead of its valid range}}
936 }
937 
938 void ptr_iter_diff(cont_with_ptr_iterator<S> &c) {
939   auto i0 = c.begin(), i1 = c.end();
940   ptrdiff_t len = i1 - i0; // no-crash
941 }
942 
943 int uninit_var(int n) {
944   int uninit; // expected-note{{'uninit' declared without an initial value}}
945   return n - uninit; // no-crash
946   // expected-warning@-1 {{The right operand of '-' is a garbage value}}
947   // expected-note@-2 {{The right operand of '-' is a garbage value}}
948 }
949