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 %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 %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 }
36 
37 // Prefix increment - operator++()
38 
39 void incr_begin(const std::vector<int> &V) {
40   auto i = V.begin();
41   ++i; // no-warning
42 }
43 
44 void incr_behind_begin(const std::vector<int> &V) {
45   auto i = ++V.begin();
46   ++i; // no-warning
47 }
48 
49 void incr_unknown(const std::vector<int> &V) {
50   auto i = return_any_iterator(V.begin());
51   ++i; // no-warning
52 }
53 
54 void incr_ahead_of_end(const std::vector<int> &V) {
55   auto i = --V.end();
56   ++i; // no-warning
57 }
58 
59 void incr_end(const std::vector<int> &V) {
60   auto i = V.end();
61   ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
62 }
63 
64 // Postfix increment - operator++(int)
65 
66 void begin_incr(const std::vector<int> &V) {
67   auto i = V.begin();
68   i++; // no-warning
69 }
70 
71 void behind_begin_incr(const std::vector<int> &V) {
72   auto i = ++V.begin();
73   i++; // no-warning
74 }
75 
76 void unknown_incr(const std::vector<int> &V) {
77   auto i = return_any_iterator(V.begin());
78   i++; // no-warning
79 }
80 
81 void ahead_of_end_incr(const std::vector<int> &V) {
82   auto i = --V.end();
83   i++; // no-warning
84 }
85 
86 void end_incr(const std::vector<int> &V) {
87   auto i = V.end();
88   i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
89 }
90 
91 // Prefix decrement - operator--()
92 
93 void decr_begin(const std::vector<int> &V) {
94   auto i = V.begin();
95   --i; // expected-warning{{Iterator decremented ahead of its valid range}}
96 }
97 
98 void decr_behind_begin(const std::vector<int> &V) {
99   auto i = ++V.begin();
100   --i; // no-warning
101 }
102 
103 void decr_unknown(const std::vector<int> &V) {
104   auto i = return_any_iterator(V.begin());
105   --i; // no-warning
106 }
107 
108 void decr_ahead_of_end(const std::vector<int> &V) {
109   auto i = --V.end();
110   --i; // no-warning
111 }
112 
113 void decr_end(const std::vector<int> &V) {
114   auto i = V.end();
115   --i; // no-warning
116 }
117 
118 // Postfix decrement - operator--(int)
119 
120 void begin_decr(const std::vector<int> &V) {
121   auto i = V.begin();
122   i--; // expected-warning{{Iterator decremented ahead of its valid range}}
123 }
124 
125 void behind_begin_decr(const std::vector<int> &V) {
126   auto i = ++V.begin();
127   i--; // no-warning
128 }
129 
130 void unknown_decr(const std::vector<int> &V) {
131   auto i = return_any_iterator(V.begin());
132   i--; // no-warning
133 }
134 
135 void ahead_of_end_decr(const std::vector<int> &V) {
136   auto i = --V.end();
137   i--; // no-warning
138 }
139 
140 void end_decr(const std::vector<int> &V) {
141   auto i = V.end();
142   i--; // no-warning
143 }
144 
145 // Addition assignment - operator+=(int)
146 
147 void incr_by_2_begin(const std::vector<int> &V) {
148   auto i = V.begin();
149   i += 2; // no-warning
150 }
151 
152 void incr_by_2_behind_begin(const std::vector<int> &V) {
153   auto i = ++V.begin();
154   i += 2; // no-warning
155 }
156 
157 void incr_by_2_unknown(const std::vector<int> &V) {
158   auto i = return_any_iterator(V.begin());
159   i += 2; // no-warning
160 }
161 
162 void incr_by_2_ahead_by_2_of_end(const std::vector<int> &V) {
163   auto i = --V.end();
164   --i;
165   i += 2; // no-warning
166 }
167 
168 void incr_by_2_ahead_of_end(const std::vector<int> &V) {
169   auto i = --V.end();
170   i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
171 }
172 
173 void incr_by_2_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 }
177 
178 // Addition - operator+(int)
179 
180 void incr_by_2_copy_begin(const std::vector<int> &V) {
181   auto i = V.begin();
182   auto j = i + 2; // no-warning
183 }
184 
185 void incr_by_2_copy_behind_begin(const std::vector<int> &V) {
186   auto i = ++V.begin();
187   auto j = i + 2; // no-warning
188 }
189 
190 void incr_by_2_copy_unknown(const std::vector<int> &V) {
191   auto i = return_any_iterator(V.begin());
192   auto j = i + 2; // no-warning
193 }
194 
195 void incr_by_2_copy_ahead_by_2_of_end(const std::vector<int> &V) {
196   auto i = --V.end();
197   --i;
198   auto j = i + 2; // no-warning
199 }
200 
201 void incr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
202   auto i = --V.end();
203   auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
204 }
205 
206 void incr_by_2_copy_end(const std::vector<int> &V) {
207   auto i = V.end();
208   auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
209 }
210 
211 // Subtraction assignment - operator-=(int)
212 
213 void decr_by_2_begin(const std::vector<int> &V) {
214   auto i = V.begin();
215   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
216 }
217 
218 void decr_by_2_behind_begin(const std::vector<int> &V) {
219   auto i = ++V.begin();
220   i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
221 }
222 
223 void decr_by_2_behind_begin_by_2(const std::vector<int> &V) {
224   auto i = ++V.begin();
225   ++i;
226   i -= 2; // no-warning
227 }
228 
229 void decr_by_2_unknown(const std::vector<int> &V) {
230   auto i = return_any_iterator(V.begin());
231   i -= 2; // no-warning
232 }
233 
234 void decr_by_2_ahead_of_end(const std::vector<int> &V) {
235   auto i = --V.end();
236   i -= 2; // no-warning
237 }
238 
239 void decr_by_2_end(const std::vector<int> &V) {
240   auto i = V.end();
241   i -= 2; // no-warning
242 }
243 
244 // Subtraction - operator-(int)
245 
246 void decr_by_2_copy_begin(const std::vector<int> &V) {
247   auto i = V.begin();
248   auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
249 }
250 
251 void decr_by_2_copy_behind_begin(const std::vector<int> &V) {
252   auto i = ++V.begin();
253   auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
254 }
255 
256 void decr_by_2_copy_behind_begin_by_2(const std::vector<int> &V) {
257   auto i = ++V.begin();
258   ++i;
259   auto j = i - 2; // no-warning
260 }
261 
262 void decr_by_2_copy_unknown(const std::vector<int> &V) {
263   auto i = return_any_iterator(V.begin());
264   auto j = i - 2; // no-warning
265 }
266 
267 void decr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
268   auto i = --V.end();
269   auto j = i - 2; // no-warning
270 }
271 
272 void decr_by_2_copy_end(const std::vector<int> &V) {
273   auto i = V.end();
274   auto j = i - 2; // no-warning
275 }
276 
277 //
278 // Subscript - operator[](int)
279 //
280 
281 // By zero
282 
283 void subscript_zero_begin(const std::vector<int> &V) {
284   auto i = V.begin();
285   auto j = i[0]; // no-warning
286 }
287 
288 void subscript_zero_behind_begin(const std::vector<int> &V) {
289   auto i = ++V.begin();
290   auto j = i[0]; // no-warning
291 }
292 
293 void subscript_zero_unknown(const std::vector<int> &V) {
294   auto i = return_any_iterator(V.begin());
295   auto j = i[0]; // no-warning
296 }
297 
298 void subscript_zero_ahead_of_end(const std::vector<int> &V) {
299   auto i = --V.end();
300   auto j = i[0]; // no-warning
301 }
302 
303 void subscript_zero_end(const std::vector<int> &V) {
304   auto i = V.end();
305   auto j = i[0]; // expected-warning{{Past-the-end iterator dereferenced}}
306 }
307 
308 // By negative number
309 
310 void subscript_negative_begin(const std::vector<int> &V) {
311   auto i = V.begin();
312   auto j = i[-1]; // no-warning FIXME: expect warning Iterator decremented ahead of its valid range
313 }
314 
315 void subscript_negative_behind_begin(const std::vector<int> &V) {
316   auto i = ++V.begin();
317   auto j = i[-1]; // no-warning
318 }
319 
320 void subscript_negative_unknown(const std::vector<int> &V) {
321   auto i = return_any_iterator(V.begin());
322   auto j = i[-1]; // no-warning
323 }
324 
325 void subscript_negative_ahead_of_end(const std::vector<int> &V) {
326   auto i = --V.end();
327   auto j = i[-1]; // no-warning
328 }
329 
330 void subscript_negative_end(const std::vector<int> &V) {
331   auto i = V.end();
332   auto j = i[-1]; // // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect no warning
333 }
334 
335 // By positive number
336 
337 void subscript_positive_begin(const std::vector<int> &V) {
338   auto i = V.begin();
339   auto j = i[1]; // no-warning
340 }
341 
342 void subscript_positive_behind_begin(const std::vector<int> &V) {
343   auto i = ++V.begin();
344   auto j = i[1]; // no-warning
345 }
346 
347 void subscript_positive_unknown(const std::vector<int> &V) {
348   auto i = return_any_iterator(V.begin());
349   auto j = i[1]; // no-warning
350 }
351 
352 void subscript_positive_ahead_of_end(const std::vector<int> &V) {
353   auto i = --V.end();
354   auto j = i[1]; // no-warning FIXME: expected warning Past-the-end iterator dereferenced
355 }
356 
357 void subscript_positive_end(const std::vector<int> &V) {
358   auto i = V.end();
359   auto j = i[1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect warning Iterator incremented behind the past-the-end iterator
360 }
361 
362 //
363 // std::advance()
364 //
365 
366 // std::advance() by +1
367 
368 void advance_plus_1_begin(const std::vector<int> &V) {
369   auto i = V.begin();
370   std::advance(i, 1); // no-warning
371 }
372 
373 void advance_plus_1_behind_begin(const std::vector<int> &V) {
374   auto i = ++V.begin();
375   std::advance(i, 1); // no-warning
376 }
377 
378 void advance_plus_1_unknown(const std::vector<int> &V) {
379   auto i = return_any_iterator(V.begin());
380   std::advance(i, 1); // no-warning
381 }
382 
383 void advance_plus_1_ahead_of_end(const std::vector<int> &V) {
384   auto i = --V.end();
385   std::advance(i, 1); // no-warning
386 }
387 
388 void advance_plus_1_end(const std::vector<int> &V) {
389   auto i = V.end();
390   std::advance(i, 1); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
391 }
392 
393 // std::advance() by -1
394 
395 void advance_minus_1_begin(const std::vector<int> &V) {
396   auto i = V.begin();
397   std::advance(i, -1); // expected-warning{{Iterator decremented ahead of its valid range}}
398 }
399 
400 void advance_minus_1_behind_begin(const std::vector<int> &V) {
401   auto i = ++V.begin();
402   std::advance(i, -1); // no-warning
403 }
404 
405 void advance_minus_1_unknown(const std::vector<int> &V) {
406   auto i = return_any_iterator(V.begin());
407   std::advance(i, -1); // no-warning
408 }
409 
410 void advance_minus_1_ahead_of_end(const std::vector<int> &V) {
411   auto i = --V.end();
412   std::advance(i, -1); // no-warning
413 }
414 
415 void advance_minus_1_end(const std::vector<int> &V) {
416   auto i = V.end();
417   std::advance(i, -1); // no-warning
418 }
419 
420 // std::advance() by +2
421 
422 void advance_plus_2_begin(const std::vector<int> &V) {
423   auto i = V.begin();
424   std::advance(i, 2); // no-warning
425 }
426 
427 void advance_plus_2_behind_begin(const std::vector<int> &V) {
428   auto i = ++V.begin();
429   std::advance(i, 2); // no-warning
430 }
431 
432 void advance_plus_2_unknown(const std::vector<int> &V) {
433   auto i = return_any_iterator(V.begin());
434   std::advance(i, 2); // no-warning
435 }
436 
437 void advance_plus_2_ahead_of_end(const std::vector<int> &V) {
438   auto i = --V.end();
439   std::advance(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
440 }
441 
442 void advance_plus_2_end(const std::vector<int> &V) {
443   auto i = V.end();
444   std::advance(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
445 }
446 
447 // std::advance() by -2
448 
449 void advance_minus_2_begin(const std::vector<int> &V) {
450   auto i = V.begin();
451   std::advance(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
452 }
453 
454 void advance_minus_2_behind_begin(const std::vector<int> &V) {
455   auto i = ++V.begin();
456   std::advance(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
457 }
458 
459 void advance_minus_2_unknown(const std::vector<int> &V) {
460   auto i = return_any_iterator(V.begin());
461   std::advance(i, -2); // no-warning
462 }
463 
464 void advance_minus_2_ahead_of_end(const std::vector<int> &V) {
465   auto i = --V.end();
466   std::advance(i, -2); // no-warning
467 }
468 
469 void advance_minus_2_end(const std::vector<int> &V) {
470   auto i = V.end();
471   std::advance(i, -2); // no-warning
472 }
473 
474 // std::advance() by 0
475 
476 void advance_0_begin(const std::vector<int> &V) {
477   auto i = V.begin();
478   std::advance(i, 0); // no-warning
479 }
480 
481 void advance_0_behind_begin(const std::vector<int> &V) {
482   auto i = ++V.begin();
483   std::advance(i, 0); // no-warning
484 }
485 
486 void advance_0_unknown(const std::vector<int> &V) {
487   auto i = return_any_iterator(V.begin());
488   std::advance(i, 0); // no-warning
489 }
490 
491 void advance_0_ahead_of_end(const std::vector<int> &V) {
492   auto i = --V.end();
493   std::advance(i, 0); // no-warning
494 }
495 
496 void advance_0_end(const std::vector<int> &V) {
497   auto i = V.end();
498   std::advance(i, 0); // no-warning
499 }
500 
501 //
502 // std::next()
503 //
504 
505 // std::next() by +1 (default)
506 
507 void next_plus_1_begin(const std::vector<int> &V) {
508   auto i = V.begin();
509   auto j = std::next(i); // no-warning
510 }
511 
512 void next_plus_1_behind_begin(const std::vector<int> &V) {
513   auto i = ++V.begin();
514   auto j = std::next(i); // no-warning
515 }
516 
517 void next_plus_1_unknown(const std::vector<int> &V) {
518   auto i = return_any_iterator(V.begin());
519   auto j = std::next(i); // no-warning
520 }
521 
522 void next_plus_1_ahead_of_end(const std::vector<int> &V) {
523   auto i = --V.end();
524   auto j = std::next(i); // no-warning
525 }
526 
527 void next_plus_1_end(const std::vector<int> &V) {
528   auto i = V.end();
529   auto j = std::next(i); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
530 }
531 
532 // std::next() by -1
533 
534 void next_minus_1_begin(const std::vector<int> &V) {
535   auto i = V.begin();
536   auto j = std::next(i, -1); // expected-warning{{Iterator decremented ahead of its valid range}}
537 }
538 
539 void next_minus_1_behind_begin(const std::vector<int> &V) {
540   auto i = ++V.begin();
541   auto j = std::next(i, -1); // no-warning
542 }
543 
544 void next_minus_1_unknown(const std::vector<int> &V) {
545   auto i = return_any_iterator(V.begin());
546   auto j = std::next(i, -1); // no-warning
547 }
548 
549 void next_minus_1_ahead_of_end(const std::vector<int> &V) {
550   auto i = --V.end();
551   auto j = std::next(i, -1); // no-warning
552 }
553 
554 void next_minus_1_end(const std::vector<int> &V) {
555   auto i = V.end();
556   auto j = std::next(i, -1); // no-warning
557 }
558 
559 // std::next() by +2
560 
561 void next_plus_2_begin(const std::vector<int> &V) {
562   auto i = V.begin();
563   auto j = std::next(i, 2); // no-warning
564 }
565 
566 void next_plus_2_behind_begin(const std::vector<int> &V) {
567   auto i = ++V.begin();
568   auto j = std::next(i, 2); // no-warning
569 }
570 
571 void next_plus_2_unknown(const std::vector<int> &V) {
572   auto i = return_any_iterator(V.begin());
573   auto j = std::next(i, 2); // no-warning
574 }
575 
576 void next_plus_2_ahead_of_end(const std::vector<int> &V) {
577   auto i = --V.end();
578   auto j = std::next(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
579 }
580 
581 void next_plus_2_end(const std::vector<int> &V) {
582   auto i = V.end();
583   auto j = std::next(i, 2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
584 }
585 
586 // std::next() by -2
587 
588 void next_minus_2_begin(const std::vector<int> &V) {
589   auto i = V.begin();
590   auto j = std::next(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
591 }
592 
593 void next_minus_2_behind_begin(const std::vector<int> &V) {
594   auto i = ++V.begin();
595   auto j = std::next(i, -2); // expected-warning{{Iterator decremented ahead of its valid range}}
596 }
597 
598 void next_minus_2_unknown(const std::vector<int> &V) {
599   auto i = return_any_iterator(V.begin());
600   auto j = std::next(i, -2); // no-warning
601 }
602 
603 void next_minus_2_ahead_of_end(const std::vector<int> &V) {
604   auto i = --V.end();
605   auto j = std::next(i, -2); // no-warning
606 }
607 
608 void next_minus_2_end(const std::vector<int> &V) {
609   auto i = V.end();
610   auto j = std::next(i, -2); // no-warning
611 }
612 
613 // std::next() by 0
614 
615 void next_0_begin(const std::vector<int> &V) {
616   auto i = V.begin();
617   auto j = std::next(i, 0); // no-warning
618 }
619 
620 void next_0_behind_begin(const std::vector<int> &V) {
621   auto i = ++V.begin();
622   auto j = std::next(i, 0); // no-warning
623 }
624 
625 void next_0_unknown(const std::vector<int> &V) {
626   auto i = return_any_iterator(V.begin());
627   auto j = std::next(i, 0); // no-warning
628 }
629 
630 void next_0_ahead_of_end(const std::vector<int> &V) {
631   auto i = --V.end();
632   auto j = std::next(i, 0); // no-warning
633 }
634 
635 void next_0_end(const std::vector<int> &V) {
636   auto i = V.end();
637   auto j = std::next(i, 0); // no-warning
638 }
639 
640 //
641 // std::prev()
642 //
643 
644 // std::prev() by +1 (default)
645 
646 void prev_plus_1_begin(const std::vector<int> &V) {
647   auto i = V.begin();
648   auto j = std::prev(i); // expected-warning{{Iterator decremented ahead of its valid range}}
649 }
650 
651 void prev_plus_1_behind_begin(const std::vector<int> &V) {
652   auto i = ++V.begin();
653   auto j = std::prev(i); // no-warning
654 }
655 
656 void prev_plus_1_unknown(const std::vector<int> &V) {
657   auto i = return_any_iterator(V.begin());
658   auto j = std::prev(i); // no-warning
659 }
660 
661 void prev_plus_1_ahead_of_end(const std::vector<int> &V) {
662   auto i = --V.end();
663   auto j = std::prev(i); // no-warning
664 }
665 
666 void prev_plus_1_end(const std::vector<int> &V) {
667   auto i = V.end();
668   auto j = std::prev(i); // no-warning
669 }
670 
671 // std::prev() by -1
672 
673 void prev_minus_1_begin(const std::vector<int> &V) {
674   auto i = V.begin();
675   auto j = std::prev(i, -1); // no-warning
676 }
677 
678 void prev_minus_1_behind_begin(const std::vector<int> &V) {
679   auto i = ++V.begin();
680   auto j = std::prev(i, -1); // no-warning
681 }
682 
683 void prev_minus_1_unknown(const std::vector<int> &V) {
684   auto i = return_any_iterator(V.begin());
685   auto j = std::prev(i, -1); // no-warning
686 }
687 
688 void prev_minus_1_ahead_of_end(const std::vector<int> &V) {
689   auto i = --V.end();
690   auto j = std::prev(i, -1); // no-warning
691 }
692 
693 void prev_minus_1_end(const std::vector<int> &V) {
694   auto i = V.end();
695   auto j = std::prev(i, -1); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
696 }
697 
698 // std::prev() by +2
699 
700 void prev_plus_2_begin(const std::vector<int> &V) {
701   auto i = V.begin();
702   auto j = std::prev(i, 2); // expected-warning{{Iterator decremented ahead of its valid range}}
703 }
704 
705 void prev_plus_2_behind_begin(const std::vector<int> &V) {
706   auto i = ++V.begin();
707   auto j = std::prev(i, 2); // expected-warning{{Iterator decremented ahead of its valid range}}
708 }
709 
710 void prev_plus_2_unknown(const std::vector<int> &V) {
711   auto i = return_any_iterator(V.begin());
712   auto j = std::prev(i, 2); // no-warning
713 }
714 
715 void prev_plus_2_ahead_of_end(const std::vector<int> &V) {
716   auto i = --V.end();
717   auto j = std::prev(i, 2); // no-warning
718 }
719 
720 void prev_plus_2_end(const std::vector<int> &V) {
721   auto i = V.end();
722   auto j = std::prev(i, 2); // no-warning
723 }
724 
725 // std::prev() by -2
726 
727 void prev_minus_2_begin(const std::vector<int> &V) {
728   auto i = V.begin();
729   auto j = std::prev(i, -2); // no-warning
730 }
731 
732 void prev_minus_2_behind_begin(const std::vector<int> &V) {
733   auto i = ++V.begin();
734   auto j = std::prev(i, -2); // no-warning
735 }
736 
737 void prev_minus_2_unknown(const std::vector<int> &V) {
738   auto i = return_any_iterator(V.begin());
739   auto j = std::prev(i, -2); // no-warning
740 }
741 
742 void prev_minus_2_ahead_of_end(const std::vector<int> &V) {
743   auto i = --V.end();
744   auto j = std::prev(i, -2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
745 }
746 
747 void prev_minus_2_end(const std::vector<int> &V) {
748   auto i = V.end();
749   auto j = std::prev(i, -2); // expected-warning{{Iterator incremented behind the past-the-end iterator}}
750 }
751 
752 // std::prev() by 0
753 
754 void prev_0_begin(const std::vector<int> &V) {
755   auto i = V.begin();
756   auto j = std::prev(i, 0); // no-warning
757 }
758 
759 void prev_0_behind_begin(const std::vector<int> &V) {
760   auto i = ++V.begin();
761   auto j = std::prev(i, 0); // no-warning
762 }
763 
764 void prev_0_unknown(const std::vector<int> &V) {
765   auto i = return_any_iterator(V.begin());
766   auto j = std::prev(i, 0); // no-warning
767 }
768 
769 void prev_0_ahead_of_end(const std::vector<int> &V) {
770   auto i = --V.end();
771   auto j = std::prev(i, 0); // no-warning
772 }
773 
774 void prev_0_end(const std::vector<int> &V) {
775   auto i = V.end();
776   auto j = std::prev(i, 0); // no-warning
777 }
778 
779 //
780 // Structure member dereference operators
781 //
782 
783 struct S {
784   int n;
785 };
786 
787 // Member dereference - operator->()
788 
789 void arrow_deref_begin(const std::vector<S> &V) {
790   auto i = V.begin();
791   int n = i->n; // no-warning
792 }
793 
794 void arrow_deref_end(const std::vector<S> &V) {
795   auto i = V.end();
796   int n = i->n; //  expected-warning{{Past-the-end iterator dereferenced}}
797 }
798