xref: /llvm-project/clang/test/Analysis/iterator-range.cpp (revision 985e399647d591d6130ba6fe08c5b5f6cb87d9f6)
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 
deref_begin(const std::vector<int> & V)10 void deref_begin(const std::vector<int> &V) {
11   auto i = V.begin();
12   *i; // no-warning
13 }
14 
deref_begind_begin(const std::vector<int> & V)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 
deref_unknown(const std::vector<int> & V)22 void deref_unknown(const std::vector<int> &V) {
23   auto i = return_any_iterator(V.begin());
24   *i; // no-warning
25 }
26 
deref_ahead_of_end(const std::vector<int> & V)27 void deref_ahead_of_end(const std::vector<int> &V) {
28   auto i = --V.end();
29   *i; // no-warning
30 }
31 
deref_end(const std::vector<int> & V)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 
incr_begin(const std::vector<int> & V)40 void incr_begin(const std::vector<int> &V) {
41   auto i = V.begin();
42   ++i; // no-warning
43 }
44 
incr_behind_begin(const std::vector<int> & V)45 void incr_behind_begin(const std::vector<int> &V) {
46   auto i = ++V.begin();
47   ++i; // no-warning
48 }
49 
incr_unknown(const std::vector<int> & V)50 void incr_unknown(const std::vector<int> &V) {
51   auto i = return_any_iterator(V.begin());
52   ++i; // no-warning
53 }
54 
incr_ahead_of_end(const std::vector<int> & V)55 void incr_ahead_of_end(const std::vector<int> &V) {
56   auto i = --V.end();
57   ++i; // no-warning
58 }
59 
incr_end(const std::vector<int> & V)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 
begin_incr(const std::vector<int> & V)68 void begin_incr(const std::vector<int> &V) {
69   auto i = V.begin();
70   i++; // no-warning
71 }
72 
behind_begin_incr(const std::vector<int> & V)73 void behind_begin_incr(const std::vector<int> &V) {
74   auto i = ++V.begin();
75   i++; // no-warning
76 }
77 
unknown_incr(const std::vector<int> & V)78 void unknown_incr(const std::vector<int> &V) {
79   auto i = return_any_iterator(V.begin());
80   i++; // no-warning
81 }
82 
ahead_of_end_incr(const std::vector<int> & V)83 void ahead_of_end_incr(const std::vector<int> &V) {
84   auto i = --V.end();
85   i++; // no-warning
86 }
87 
end_incr(const std::vector<int> & V)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 
decr_begin(const std::vector<int> & V)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 
decr_behind_begin(const std::vector<int> & V)102 void decr_behind_begin(const std::vector<int> &V) {
103   auto i = ++V.begin();
104   --i; // no-warning
105 }
106 
decr_unknown(const std::vector<int> & V)107 void decr_unknown(const std::vector<int> &V) {
108   auto i = return_any_iterator(V.begin());
109   --i; // no-warning
110 }
111 
decr_ahead_of_end(const std::vector<int> & V)112 void decr_ahead_of_end(const std::vector<int> &V) {
113   auto i = --V.end();
114   --i; // no-warning
115 }
116 
decr_end(const std::vector<int> & V)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 
begin_decr(const std::vector<int> & V)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 
behind_begin_decr(const std::vector<int> & V)130 void behind_begin_decr(const std::vector<int> &V) {
131   auto i = ++V.begin();
132   i--; // no-warning
133 }
134 
unknown_decr(const std::vector<int> & V)135 void unknown_decr(const std::vector<int> &V) {
136   auto i = return_any_iterator(V.begin());
137   i--; // no-warning
138 }
139 
ahead_of_end_decr(const std::vector<int> & V)140 void ahead_of_end_decr(const std::vector<int> &V) {
141   auto i = --V.end();
142   i--; // no-warning
143 }
144 
end_decr(const std::vector<int> & V)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 
incr_by_2_begin(const std::vector<int> & V)152 void incr_by_2_begin(const std::vector<int> &V) {
153   auto i = V.begin();
154   i += 2; // no-warning
155 }
156 
incr_by_2_behind_begin(const std::vector<int> & V)157 void incr_by_2_behind_begin(const std::vector<int> &V) {
158   auto i = ++V.begin();
159   i += 2; // no-warning
160 }
161 
incr_by_2_unknown(const std::vector<int> & V)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 
incr_by_2_ahead_by_2_of_end(const std::vector<int> & V)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 
incr_by_2_ahead_of_end(const std::vector<int> & V)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 
incr_by_2_end(const std::vector<int> & V)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 
incr_by_2_copy_begin(const std::vector<int> & V)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 
incr_by_2_copy_behind_begin(const std::vector<int> & V)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 
incr_by_2_copy_unknown(const std::vector<int> & V)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 
incr_by_2_copy_ahead_by_2_of_end(const std::vector<int> & V)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 
incr_by_2_copy_ahead_of_end(const std::vector<int> & V)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 
incr_by_2_copy_end(const std::vector<int> & V)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 
decr_by_2_begin(const std::vector<int> & V)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 
decr_by_2_behind_begin(const std::vector<int> & V)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 
decr_by_2_behind_begin_by_2(const std::vector<int> & V)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 
decr_by_2_unknown(const std::vector<int> & V)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 
decr_by_2_ahead_of_end(const std::vector<int> & V)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 
decr_by_2_end(const std::vector<int> & V)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 
decr_by_2_copy_begin(const std::vector<int> & V)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 
decr_by_2_copy_behind_begin(const std::vector<int> & V)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 
decr_by_2_copy_behind_begin_by_2(const std::vector<int> & V)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 
decr_by_2_copy_unknown(const std::vector<int> & V)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 
decr_by_2_copy_ahead_of_end(const std::vector<int> & V)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 
decr_by_2_copy_end(const std::vector<int> & V)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 
subscript_zero_begin(const std::vector<int> & V)296 void subscript_zero_begin(const std::vector<int> &V) {
297   auto i = V.begin();
298   auto j = i[0]; // no-warning
299 }
300 
subscript_zero_behind_begin(const std::vector<int> & V)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 
subscript_zero_unknown(const std::vector<int> & V)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 
subscript_zero_ahead_of_end(const std::vector<int> & V)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 
subscript_zero_end(const std::vector<int> & V)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 
subscript_negative_begin(const std::vector<int> & V)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 
subscript_negative_behind_begin(const std::vector<int> & V)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 
subscript_negative_unknown(const std::vector<int> & V)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 
subscript_negative_ahead_of_end(const std::vector<int> & V)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 
subscript_negative_end(const std::vector<int> & V)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 
subscript_positive_begin(const std::vector<int> & V)352 void subscript_positive_begin(const std::vector<int> &V) {
353   auto i = V.begin();
354   auto j = i[1]; // no-warning
355 }
356 
subscript_positive_behind_begin(const std::vector<int> & V)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 
subscript_positive_unknown(const std::vector<int> & V)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 
subscript_positive_ahead_of_end(const std::vector<int> & V)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 
subscript_positive_end(const std::vector<int> & V)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 
advance_plus_1_begin(const std::vector<int> & V)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 
advance_plus_1_behind_begin(const std::vector<int> & V)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 
advance_plus_1_unknown(const std::vector<int> & V)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 
advance_plus_1_ahead_of_end(const std::vector<int> & V)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 
advance_plus_1_end(const std::vector<int> & V)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 
advance_minus_1_begin(const std::vector<int> & V)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 
advance_minus_1_behind_begin(const std::vector<int> & V)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 
advance_minus_1_unknown(const std::vector<int> & V)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 
advance_minus_1_ahead_of_end(const std::vector<int> & V)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 
advance_minus_1_end(const std::vector<int> & V)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 
advance_plus_2_begin(const std::vector<int> & V)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 
advance_plus_2_behind_begin(const std::vector<int> & V)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 
advance_plus_2_unknown(const std::vector<int> & V)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 
advance_plus_2_ahead_of_end(const std::vector<int> & V)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 
advance_plus_2_end(const std::vector<int> & V)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 
advance_minus_2_begin(const std::vector<int> & V)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 
advance_minus_2_behind_begin(const std::vector<int> & V)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 
advance_minus_2_unknown(const std::vector<int> & V)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 
advance_minus_2_ahead_of_end(const std::vector<int> & V)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 
advance_minus_2_end(const std::vector<int> & V)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 
advance_0_begin(const std::vector<int> & V)498 void advance_0_begin(const std::vector<int> &V) {
499   auto i = V.begin();
500   std::advance(i, 0); // no-warning
501 }
502 
advance_0_behind_begin(const std::vector<int> & V)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 
advance_0_unknown(const std::vector<int> & V)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 
advance_0_ahead_of_end(const std::vector<int> & V)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 
advance_0_end(const std::vector<int> & V)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 
next_plus_1_begin(const std::vector<int> & V)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 
next_plus_1_behind_begin(const std::vector<int> & V)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 
next_plus_1_unknown(const std::vector<int> & V)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 
next_plus_1_ahead_of_end(const std::vector<int> & V)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 
next_plus_1_end(const std::vector<int> & V)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 
next_minus_1_begin(const std::vector<int> & V)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 
next_minus_1_behind_begin(const std::vector<int> & V)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 
next_minus_1_unknown(const std::vector<int> & V)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 
next_minus_1_ahead_of_end(const std::vector<int> & V)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 
next_minus_1_end(const std::vector<int> & V)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 
next_plus_2_begin(const std::vector<int> & V)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 
next_plus_2_behind_begin(const std::vector<int> & V)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 
next_plus_2_unknown(const std::vector<int> & V)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 
next_plus_2_ahead_of_end(const std::vector<int> & V)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 
next_plus_2_end(const std::vector<int> & V)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 
next_minus_2_begin(const std::vector<int> & V)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 
next_minus_2_behind_begin(const std::vector<int> & V)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 
next_minus_2_unknown(const std::vector<int> & V)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 
next_minus_2_ahead_of_end(const std::vector<int> & V)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 
next_minus_2_end(const std::vector<int> & V)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 
next_0_begin(const std::vector<int> & V)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 
next_0_behind_begin(const std::vector<int> & V)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 
next_0_unknown(const std::vector<int> & V)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 
next_0_ahead_of_end(const std::vector<int> & V)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 
next_0_end(const std::vector<int> & V)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 
prev_plus_1_begin(const std::vector<int> & V)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 
prev_plus_1_behind_begin(const std::vector<int> & V)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 
prev_plus_1_unknown(const std::vector<int> & V)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 
prev_plus_1_ahead_of_end(const std::vector<int> & V)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 
prev_plus_1_end(const std::vector<int> & V)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 
prev_minus_1_begin(const std::vector<int> & V)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 
prev_minus_1_behind_begin(const std::vector<int> & V)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 
prev_minus_1_unknown(const std::vector<int> & V)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 
prev_minus_1_ahead_of_end(const std::vector<int> & V)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 
prev_minus_1_end(const std::vector<int> & V)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 
prev_plus_2_begin(const std::vector<int> & V)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 
prev_plus_2_behind_begin(const std::vector<int> & V)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 
prev_plus_2_unknown(const std::vector<int> & V)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 
prev_plus_2_ahead_of_end(const std::vector<int> & V)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 
prev_plus_2_end(const std::vector<int> & V)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 
prev_minus_2_begin(const std::vector<int> & V)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 
prev_minus_2_behind_begin(const std::vector<int> & V)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 
prev_minus_2_unknown(const std::vector<int> & V)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 
prev_minus_2_ahead_of_end(const std::vector<int> & V)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 
prev_minus_2_end(const std::vector<int> & V)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 
prev_0_begin(const std::vector<int> & V)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 
prev_0_behind_begin(const std::vector<int> & V)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 
prev_0_unknown(const std::vector<int> & V)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 
prev_0_ahead_of_end(const std::vector<int> & V)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 
prev_0_end(const std::vector<int> & V)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 
prev_loc_value(const std::vector<int> & V,int o)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 
arrow_deref_begin(const std::vector<S> & V)836 void arrow_deref_begin(const std::vector<S> &V) {
837   auto i = V.begin();
838   int n = i->n; // no-warning
839 }
840 
arrow_deref_end(const std::vector<S> & V)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 
deref_end_after_pop_back(std::vector<int> & V)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 
deref_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
array_deref_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
arrow_deref_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
arrow_star_deref_end_ptr_iterator(const cont_with_ptr_iterator<S> & c,int S::* p)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 
prefix_incr_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
postfix_incr_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
prefix_decr_begin_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
postfix_decr_begin_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
prefix_add_2_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
postfix_add_assign_2_end_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
prefix_minus_2_begin_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
postfix_minus_assign_2_begin_ptr_iterator(const cont_with_ptr_iterator<S> & c)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 
ptr_iter_diff(cont_with_ptr_iterator<S> & c)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 
uninit_var(int n)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 
950 namespace std {
951 namespace ranges {
952   template <class InOutIter, class Sentinel>
953   InOutIter next(InOutIter, Sentinel);
954 } // namespace ranges
955 } // namespace std
956 
gh65009__no_crash_on_ranges_next(int ** begin,int ** end)957 void gh65009__no_crash_on_ranges_next(int **begin, int **end) {
958   (void)std::ranges::next(begin, end); // no-crash
959 }
960