[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / test / Analysis / iterator-range.cpp
blob849a1e9814ae39face982347c4f04454fa6bfc2f
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
4 #include "Inputs/system-header-simulator-cxx.h"
6 void clang_analyzer_warnIfReached();
8 // Dereference - operator*()
10 void deref_begin(const std::vector<int> &V) {
11 auto i = V.begin();
12 *i; // no-warning
15 void deref_begind_begin(const std::vector<int> &V) {
16 auto i = ++V.begin();
17 *i; // no-warning
20 template <typename Iter> Iter return_any_iterator(const Iter &It);
22 void deref_unknown(const std::vector<int> &V) {
23 auto i = return_any_iterator(V.begin());
24 *i; // no-warning
27 void deref_ahead_of_end(const std::vector<int> &V) {
28 auto i = --V.end();
29 *i; // no-warning
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}}
38 // Prefix increment - operator++()
40 void incr_begin(const std::vector<int> &V) {
41 auto i = V.begin();
42 ++i; // no-warning
45 void incr_behind_begin(const std::vector<int> &V) {
46 auto i = ++V.begin();
47 ++i; // no-warning
50 void incr_unknown(const std::vector<int> &V) {
51 auto i = return_any_iterator(V.begin());
52 ++i; // no-warning
55 void incr_ahead_of_end(const std::vector<int> &V) {
56 auto i = --V.end();
57 ++i; // no-warning
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}}
66 // Postfix increment - operator++(int)
68 void begin_incr(const std::vector<int> &V) {
69 auto i = V.begin();
70 i++; // no-warning
73 void behind_begin_incr(const std::vector<int> &V) {
74 auto i = ++V.begin();
75 i++; // no-warning
78 void unknown_incr(const std::vector<int> &V) {
79 auto i = return_any_iterator(V.begin());
80 i++; // no-warning
83 void ahead_of_end_incr(const std::vector<int> &V) {
84 auto i = --V.end();
85 i++; // no-warning
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}}
94 // Prefix decrement - operator--()
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}}
102 void decr_behind_begin(const std::vector<int> &V) {
103 auto i = ++V.begin();
104 --i; // no-warning
107 void decr_unknown(const std::vector<int> &V) {
108 auto i = return_any_iterator(V.begin());
109 --i; // no-warning
112 void decr_ahead_of_end(const std::vector<int> &V) {
113 auto i = --V.end();
114 --i; // no-warning
117 void decr_end(const std::vector<int> &V) {
118 auto i = V.end();
119 --i; // no-warning
122 // Postfix decrement - operator--(int)
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}}
130 void behind_begin_decr(const std::vector<int> &V) {
131 auto i = ++V.begin();
132 i--; // no-warning
135 void unknown_decr(const std::vector<int> &V) {
136 auto i = return_any_iterator(V.begin());
137 i--; // no-warning
140 void ahead_of_end_decr(const std::vector<int> &V) {
141 auto i = --V.end();
142 i--; // no-warning
145 void end_decr(const std::vector<int> &V) {
146 auto i = V.end();
147 i--; // no-warning
150 // Addition assignment - operator+=(int)
152 void incr_by_2_begin(const std::vector<int> &V) {
153 auto i = V.begin();
154 i += 2; // no-warning
157 void incr_by_2_behind_begin(const std::vector<int> &V) {
158 auto i = ++V.begin();
159 i += 2; // no-warning
162 void incr_by_2_unknown(const std::vector<int> &V) {
163 auto i = return_any_iterator(V.begin());
164 i += 2; // no-warning
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
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}}
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}}
185 // Addition - operator+(int)
187 void incr_by_2_copy_begin(const std::vector<int> &V) {
188 auto i = V.begin();
189 auto j = i + 2; // no-warning
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
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
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
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}}
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}}
220 // Subtraction assignment - operator-=(int)
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}}
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}}
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
240 void decr_by_2_unknown(const std::vector<int> &V) {
241 auto i = return_any_iterator(V.begin());
242 i -= 2; // no-warning
245 void decr_by_2_ahead_of_end(const std::vector<int> &V) {
246 auto i = --V.end();
247 i -= 2; // no-warning
250 void decr_by_2_end(const std::vector<int> &V) {
251 auto i = V.end();
252 i -= 2; // no-warning
255 // Subtraction - operator-(int)
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}}
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}}
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
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
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
285 void decr_by_2_copy_end(const std::vector<int> &V) {
286 auto i = V.end();
287 auto j = i - 2; // no-warning
291 // Subscript - operator[](int)
294 // By zero
296 void subscript_zero_begin(const std::vector<int> &V) {
297 auto i = V.begin();
298 auto j = i[0]; // no-warning
301 void subscript_zero_behind_begin(const std::vector<int> &V) {
302 auto i = ++V.begin();
303 auto j = i[0]; // no-warning
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
311 void subscript_zero_ahead_of_end(const std::vector<int> &V) {
312 auto i = --V.end();
313 auto j = i[0]; // no-warning
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}}
322 // By negative number
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
329 void subscript_negative_behind_begin(const std::vector<int> &V) {
330 auto i = ++V.begin();
331 auto j = i[-1]; // no-warning
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
339 void subscript_negative_ahead_of_end(const std::vector<int> &V) {
340 auto i = --V.end();
341 auto j = i[-1]; // no-warning
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}}
350 // By positive number
352 void subscript_positive_begin(const std::vector<int> &V) {
353 auto i = V.begin();
354 auto j = i[1]; // no-warning
357 void subscript_positive_behind_begin(const std::vector<int> &V) {
358 auto i = ++V.begin();
359 auto j = i[1]; // no-warning
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
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
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
379 // std::advance()
382 // std::advance() by +1
384 void advance_plus_1_begin(const std::vector<int> &V) {
385 auto i = V.begin();
386 std::advance(i, 1); // no-warning
389 void advance_plus_1_behind_begin(const std::vector<int> &V) {
390 auto i = ++V.begin();
391 std::advance(i, 1); // no-warning
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
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
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}}
410 // std::advance() by -1
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}}
418 void advance_minus_1_behind_begin(const std::vector<int> &V) {
419 auto i = ++V.begin();
420 std::advance(i, -1); // no-warning
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
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
433 void advance_minus_1_end(const std::vector<int> &V) {
434 auto i = V.end();
435 std::advance(i, -1); // no-warning
438 // std::advance() by +2
440 void advance_plus_2_begin(const std::vector<int> &V) {
441 auto i = V.begin();
442 std::advance(i, 2); // no-warning
445 void advance_plus_2_behind_begin(const std::vector<int> &V) {
446 auto i = ++V.begin();
447 std::advance(i, 2); // no-warning
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
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}}
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}}
467 // std::advance() by -2
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}}
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}}
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
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
491 void advance_minus_2_end(const std::vector<int> &V) {
492 auto i = V.end();
493 std::advance(i, -2); // no-warning
496 // std::advance() by 0
498 void advance_0_begin(const std::vector<int> &V) {
499 auto i = V.begin();
500 std::advance(i, 0); // no-warning
503 void advance_0_behind_begin(const std::vector<int> &V) {
504 auto i = ++V.begin();
505 std::advance(i, 0); // no-warning
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
513 void advance_0_ahead_of_end(const std::vector<int> &V) {
514 auto i = --V.end();
515 std::advance(i, 0); // no-warning
518 void advance_0_end(const std::vector<int> &V) {
519 auto i = V.end();
520 std::advance(i, 0); // no-warning
524 // std::next()
527 // std::next() by +1 (default)
529 void next_plus_1_begin(const std::vector<int> &V) {
530 auto i = V.begin();
531 auto j = std::next(i); // no-warning
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
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
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
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}}
555 // std::next() by -1
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}}
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
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
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
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
583 // std::next() by +2
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
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
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
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}}
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}}
612 // std::next() by -2
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}}
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}}
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
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
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
641 // std::next() by 0
643 void next_0_begin(const std::vector<int> &V) {
644 auto i = V.begin();
645 auto j = std::next(i, 0); // no-warning
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
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
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
663 void next_0_end(const std::vector<int> &V) {
664 auto i = V.end();
665 auto j = std::next(i, 0); // no-warning
669 // std::prev()
672 // std::prev() by +1 (default)
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}}
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
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
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
695 void prev_plus_1_end(const std::vector<int> &V) {
696 auto i = V.end();
697 auto j = std::prev(i); // no-warning
700 // std::prev() by -1
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
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
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
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
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}}
728 // std::prev() by +2
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}}
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}}
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
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
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
757 // std::prev() by -2
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
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
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
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}}
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}}
786 // std::prev() by 0
788 void prev_0_begin(const std::vector<int> &V) {
789 auto i = V.begin();
790 auto j = std::prev(i, 0); // no-warning
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
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
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
808 void prev_0_end(const std::vector<int> &V) {
809 auto i = V.end();
810 auto j = std::prev(i, 0); // no-warning
813 // std::prev() with int* for checking Loc value argument
814 namespace std {
815 template <typename T>
816 T prev(T, int *);
819 void prev_loc_value(const std::vector<int> &V, int o) {
821 auto i = return_any_iterator(V.begin());
822 int *offset = &o;
823 auto j = std::prev(i, offset); // no-warning
827 // Structure member dereference operators
830 struct S {
831 int n;
834 // Member dereference - operator->()
836 void arrow_deref_begin(const std::vector<S> &V) {
837 auto i = V.begin();
838 int n = i->n; // no-warning
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}}
847 // Container modification - test path notes
849 void deref_end_after_pop_back(std::vector<int> &V) {
850 const auto i = --V.end();
852 V.pop_back(); // expected-note{{Container 'V' shrank from the back by 1 position}}
854 *i; // expected-warning{{Past-the-end iterator dereferenced}}
855 // expected-note@-1{{Past-the-end iterator dereferenced}}
858 template<typename T>
859 struct cont_with_ptr_iterator {
860 T* begin() const;
861 T* end() const;
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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}}
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
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}}