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 // Structure member dereference operators 364 // 365 366 struct S { 367 int n; 368 }; 369 370 // Member dereference - operator->() 371 372 void arrow_deref_begin(const std::vector<S> &V) { 373 auto i = V.begin(); 374 int n = i->n; // no-warning 375 } 376 377 void arrow_deref_end(const std::vector<S> &V) { 378 auto i = V.end(); 379 int n = i->n; // expected-warning{{Past-the-end iterator dereferenced}} 380 } 381