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 good_push_back(std::list<int> &L, int n) { 119 auto i0 = --L.cend(); 120 L.push_back(n); 121 *++i0; // no-warning 122 } 123 124 void bad_push_back(std::list<int> &L, int n) { 125 auto i0 = --L.cend(); 126 L.push_back(n); 127 ++i0; 128 *++i0; // expected-warning{{Iterator accessed outside of its range}} 129 } 130 131 void good_pop_back(std::list<int> &L, int n) { 132 auto i0 = --L.cend(); --i0; 133 L.pop_back(); 134 *i0; // no-warning 135 } 136 137 void bad_pop_back(std::list<int> &L, int n) { 138 auto i0 = --L.cend(); --i0; 139 L.pop_back(); 140 *++i0; // expected-warning{{Iterator accessed outside of its range}} 141 } 142 143 void good_push_front(std::list<int> &L, int n) { 144 auto i0 = L.cbegin(); 145 L.push_front(n); 146 *--i0; // no-warning 147 } 148 149 void bad_push_front(std::list<int> &L, int n) { 150 auto i0 = L.cbegin(); 151 L.push_front(n); 152 --i0; 153 *--i0; // expected-warning{{Iterator accessed outside of its range}} 154 } 155 156 void good_pop_front(std::list<int> &L, int n) { 157 auto i0 = ++L.cbegin(); 158 L.pop_front(); 159 *i0; // no-warning 160 } 161 162 void bad_pop_front(std::list<int> &L, int n) { 163 auto i0 = ++L.cbegin(); 164 L.pop_front(); 165 *--i0; // expected-warning{{Iterator accessed outside of its range}} 166 } 167 168 void bad_move(std::list<int> &L1, std::list<int> &L2) { 169 auto i0 = --L2.cend(); 170 L1 = std::move(L2); 171 *++i0; // expected-warning{{Iterator accessed outside of its range}} 172 } 173 174 void bad_move_push_back(std::list<int> &L1, std::list<int> &L2, int n) { 175 auto i0 = --L2.cend(); 176 L2.push_back(n); 177 L1 = std::move(L2); 178 ++i0; 179 *++i0; // expected-warning{{Iterator accessed outside of its range}} 180 } 181