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