1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.InvalidatedIterator -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.InvalidatedIterator -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 normal_dereference(std::vector<int> & V)8void normal_dereference(std::vector<int> &V) { 9 auto i = V.cbegin(); 10 *i; // no-warning 11 } 12 invalidated_dereference(std::vector<int> & V)13void invalidated_dereference(std::vector<int> &V) { 14 auto i = V.cbegin(); 15 V.erase(i); 16 *i; // expected-warning{{Invalidated iterator accessed}} 17 } 18 normal_prefix_increment(std::vector<int> & V)19void normal_prefix_increment(std::vector<int> &V) { 20 auto i = V.cbegin(); 21 ++i; // no-warning 22 } 23 invalidated_prefix_increment(std::vector<int> & V)24void invalidated_prefix_increment(std::vector<int> &V) { 25 auto i = V.cbegin(); 26 V.erase(i); 27 ++i; // expected-warning{{Invalidated iterator accessed}} 28 } 29 normal_prefix_decrement(std::vector<int> & V)30void normal_prefix_decrement(std::vector<int> &V) { 31 auto i = ++V.cbegin(); 32 --i; // no-warning 33 } 34 invalidated_prefix_decrement(std::vector<int> & V)35void invalidated_prefix_decrement(std::vector<int> &V) { 36 auto i = ++V.cbegin(); 37 V.erase(i); 38 --i; // expected-warning{{Invalidated iterator accessed}} 39 } 40 normal_postfix_increment(std::vector<int> & V)41void normal_postfix_increment(std::vector<int> &V) { 42 auto i = V.cbegin(); 43 i++; // no-warning 44 } 45 invalidated_postfix_increment(std::vector<int> & V)46void invalidated_postfix_increment(std::vector<int> &V) { 47 auto i = V.cbegin(); 48 V.erase(i); 49 i++; // expected-warning{{Invalidated iterator accessed}} 50 } 51 normal_postfix_decrement(std::vector<int> & V)52void normal_postfix_decrement(std::vector<int> &V) { 53 auto i = ++V.cbegin(); 54 i--; // no-warning 55 } 56 invalidated_postfix_decrement(std::vector<int> & V)57void invalidated_postfix_decrement(std::vector<int> &V) { 58 auto i = ++V.cbegin(); 59 V.erase(i); 60 i--; // expected-warning{{Invalidated iterator accessed}} 61 } 62 normal_increment_by_2(std::vector<int> & V)63void normal_increment_by_2(std::vector<int> &V) { 64 auto i = V.cbegin(); 65 i += 2; // no-warning 66 } 67 invalidated_increment_by_2(std::vector<int> & V)68void invalidated_increment_by_2(std::vector<int> &V) { 69 auto i = V.cbegin(); 70 V.erase(i); 71 i += 2; // expected-warning{{Invalidated iterator accessed}} 72 } 73 normal_increment_by_2_copy(std::vector<int> & V)74void normal_increment_by_2_copy(std::vector<int> &V) { 75 auto i = V.cbegin(); 76 auto j = i + 2; // no-warning 77 } 78 invalidated_increment_by_2_copy(std::vector<int> & V)79void invalidated_increment_by_2_copy(std::vector<int> &V) { 80 auto i = V.cbegin(); 81 V.erase(i); 82 auto j = i + 2; // expected-warning{{Invalidated iterator accessed}} 83 } 84 normal_decrement_by_2(std::vector<int> & V)85void normal_decrement_by_2(std::vector<int> &V) { 86 auto i = V.cbegin(); 87 i -= 2; // no-warning 88 } 89 invalidated_decrement_by_2(std::vector<int> & V)90void invalidated_decrement_by_2(std::vector<int> &V) { 91 auto i = V.cbegin(); 92 V.erase(i); 93 i -= 2; // expected-warning{{Invalidated iterator accessed}} 94 } 95 normal_decrement_by_2_copy(std::vector<int> & V)96void normal_decrement_by_2_copy(std::vector<int> &V) { 97 auto i = V.cbegin(); 98 auto j = i - 2; // no-warning 99 } 100 invalidated_decrement_by_2_copy(std::vector<int> & V)101void invalidated_decrement_by_2_copy(std::vector<int> &V) { 102 auto i = V.cbegin(); 103 V.erase(i); 104 auto j = i - 2; // expected-warning{{Invalidated iterator accessed}} 105 } 106 normal_subscript(std::vector<int> & V)107void normal_subscript(std::vector<int> &V) { 108 auto i = V.cbegin(); 109 i[1]; // no-warning 110 } 111 invalidated_subscript(std::vector<int> & V)112void invalidated_subscript(std::vector<int> &V) { 113 auto i = V.cbegin(); 114 V.erase(i); 115 i[1]; // expected-warning{{Invalidated iterator accessed}} 116 } 117 assignment(std::vector<int> & V)118void assignment(std::vector<int> &V) { 119 auto i = V.cbegin(); 120 V.erase(i); 121 auto j = V.cbegin(); // no-warning 122 } 123 124 template<typename T> 125 struct cont_with_ptr_iterator { 126 T *begin() const; 127 T *end() const; 128 T &operator[](size_t); 129 void push_back(const T&); 130 T* erase(T*); 131 }; 132 invalidated_access_via_end_iterator_after_push_back()133void invalidated_access_via_end_iterator_after_push_back() { 134 cont_with_ptr_iterator<int> C; 135 C.push_back(1); 136 auto i = C.end(); 137 C.push_back(2); 138 auto j = i[-1]; // expected-warning{{Invalidated iterator accessed}} 139 } 140 invalidated_dereference_end_ptr_iterator(cont_with_ptr_iterator<int> & C)141void invalidated_dereference_end_ptr_iterator(cont_with_ptr_iterator<int> &C) { 142 auto i = C.begin(); 143 C.erase(i); 144 (void) *i; // expected-warning{{Invalidated iterator accessed}} 145 } 146 invalidated_prefix_increment_end_ptr_iterator(cont_with_ptr_iterator<int> & C)147void invalidated_prefix_increment_end_ptr_iterator( 148 cont_with_ptr_iterator<int> &C) { 149 auto i = C.begin(); 150 C.erase(i); 151 ++i; // expected-warning{{Invalidated iterator accessed}} 152 } 153 invalidated_prefix_decrement_end_ptr_iterator(cont_with_ptr_iterator<int> & C)154void invalidated_prefix_decrement_end_ptr_iterator( 155 cont_with_ptr_iterator<int> &C) { 156 auto i = C.begin() + 1; 157 C.erase(i); 158 --i; // expected-warning{{Invalidated iterator accessed}} 159 } 160 invalidated_postfix_increment_end_ptr_iterator(cont_with_ptr_iterator<int> & C)161void invalidated_postfix_increment_end_ptr_iterator( 162 cont_with_ptr_iterator<int> &C) { 163 auto i = C.begin(); 164 C.erase(i); 165 i++; // expected-warning{{Invalidated iterator accessed}} 166 } 167 invalidated_postfix_decrement_end_ptr_iterator(cont_with_ptr_iterator<int> & C)168void invalidated_postfix_decrement_end_ptr_iterator( 169 cont_with_ptr_iterator<int> &C) { 170 auto i = C.begin() + 1; 171 C.erase(i); 172 i--; // expected-warning{{Invalidated iterator accessed}} 173 } 174 invalidated_increment_by_2_end_ptr_iterator(cont_with_ptr_iterator<int> & C)175void invalidated_increment_by_2_end_ptr_iterator( 176 cont_with_ptr_iterator<int> &C) { 177 auto i = C.begin(); 178 C.erase(i); 179 i += 2; // expected-warning{{Invalidated iterator accessed}} 180 } 181 invalidated_increment_by_2_copy_end_ptr_iterator(cont_with_ptr_iterator<int> & C)182void invalidated_increment_by_2_copy_end_ptr_iterator( 183 cont_with_ptr_iterator<int> &C) { 184 auto i = C.begin(); 185 C.erase(i); 186 auto j = i + 2; // expected-warning{{Invalidated iterator accessed}} 187 } 188 invalidated_decrement_by_2_end_ptr_iterator(cont_with_ptr_iterator<int> & C)189void invalidated_decrement_by_2_end_ptr_iterator( 190 cont_with_ptr_iterator<int> &C) { 191 auto i = C.begin(); 192 C.erase(i); 193 i -= 2; // expected-warning{{Invalidated iterator accessed}} 194 } 195 invalidated_decrement_by_2_copy_end_ptr_iterator(cont_with_ptr_iterator<int> & C)196void invalidated_decrement_by_2_copy_end_ptr_iterator( 197 cont_with_ptr_iterator<int> &C) { 198 auto i = C.begin(); 199 C.erase(i); 200 auto j = i - 2; // expected-warning{{Invalidated iterator accessed}} 201 } 202 invalidated_subscript_end_ptr_iterator(cont_with_ptr_iterator<int> & C)203void invalidated_subscript_end_ptr_iterator(cont_with_ptr_iterator<int> &C) { 204 auto i = C.begin(); 205 C.erase(i); 206 (void) i[1]; // expected-warning{{Invalidated iterator accessed}} 207 }