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 void simple_good_end(const std::vector<int> &v) { 9 auto i = v.end(); 10 if (i != v.end()) { 11 clang_analyzer_warnIfReached(); 12 *i; // no-warning 13 } 14 } 15 16 void simple_good_end_negated(const std::vector<int> &v) { 17 auto i = v.end(); 18 if (!(i == v.end())) { 19 clang_analyzer_warnIfReached(); 20 *i; // no-warning 21 } 22 } 23 24 void simple_bad_end(const std::vector<int> &v) { 25 auto i = v.end(); 26 *i; // expected-warning{{Iterator accessed outside of its range}} 27 } 28 29 void simple_good_begin(const std::vector<int> &v) { 30 auto i = v.begin(); 31 if (i != v.begin()) { 32 clang_analyzer_warnIfReached(); 33 *--i; // no-warning 34 } 35 } 36 37 void simple_good_begin_negated(const std::vector<int> &v) { 38 auto i = v.begin(); 39 if (!(i == v.begin())) { 40 clang_analyzer_warnIfReached(); 41 *--i; // no-warning 42 } 43 } 44 45 void simple_bad_begin(const std::vector<int> &v) { 46 auto i = v.begin(); 47 *--i; // expected-warning{{Iterator accessed outside of its range}} 48 } 49 50 void copy(const std::vector<int> &v) { 51 auto i1 = v.end(); 52 auto i2 = i1; 53 *i2; // expected-warning{{Iterator accessed outside of its range}} 54 } 55 56 void decrease(const std::vector<int> &v) { 57 auto i = v.end(); 58 --i; 59 *i; // no-warning 60 } 61 62 void copy_and_decrease1(const std::vector<int> &v) { 63 auto i1 = v.end(); 64 auto i2 = i1; 65 --i1; 66 *i1; // no-warning 67 } 68 69 void copy_and_decrease2(const std::vector<int> &v) { 70 auto i1 = v.end(); 71 auto i2 = i1; 72 --i1; 73 *i2; // expected-warning{{Iterator accessed outside of its range}} 74 } 75 76 void copy_and_increase1(const std::vector<int> &v) { 77 auto i1 = v.begin(); 78 auto i2 = i1; 79 ++i1; 80 if (i1 == v.end()) 81 *i2; // no-warning 82 } 83 84 void copy_and_increase2(const std::vector<int> &v) { 85 auto i1 = v.begin(); 86 auto i2 = i1; 87 ++i1; 88 if (i2 == v.end()) 89 *i2; // expected-warning{{Iterator accessed outside of its range}} 90 } 91 92 void copy_and_increase3(const std::vector<int> &v) { 93 auto i1 = v.begin(); 94 auto i2 = i1; 95 ++i1; 96 if (v.end() == i2) 97 *i2; // expected-warning{{Iterator accessed outside of its range}} 98 } 99 100 void tricky(std::vector<int> &V, int e) { 101 const auto first = V.begin(); 102 const auto comp1 = (first != V.end()), comp2 = (first == V.end()); 103 if (comp1) 104 *first; 105 } 106 107 void loop(std::vector<int> &V, int e) { 108 auto start = V.begin(); 109 while (true) { 110 auto item = std::find(start, V.end(), e); 111 if (item == V.end()) 112 break; 113 *item; // no-warning 114 start = ++item; // no-warning 115 } 116 } 117 118 void bad_move(std::list<int> &L1, std::list<int> &L2) { 119 auto i0 = --L2.cend(); 120 L1 = std::move(L2); 121 *++i0; // expected-warning{{Iterator accessed outside of its range}} 122 } 123