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