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