1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify -analyzer-config display-checker-name=false 2 3 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify -analyzer-config display-checker-name=false 4 5 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify -analyzer-config display-checker-name=false 6 7 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify -analyzer-config display-checker-name=false 8 9 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify -analyzer-config display-checker-name=false 10 11 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s 12 13 #include "Inputs/system-header-simulator-cxx.h" 14 15 template <typename Container> 16 long clang_analyzer_container_begin(const Container&); 17 template <typename Container> 18 long clang_analyzer_container_end(const Container&); 19 template <typename Iterator> 20 long clang_analyzer_iterator_position(const Iterator&); 21 long clang_analyzer_iterator_position(int*); 22 template <typename Iterator> 23 void* clang_analyzer_iterator_container(const Iterator&); 24 template <typename Iterator> 25 bool clang_analyzer_iterator_validity(const Iterator&); 26 27 void clang_analyzer_denote(long, const char*); 28 void clang_analyzer_express(long); 29 void clang_analyzer_eval(bool); 30 void clang_analyzer_warnIfReached(); 31 32 void begin(const std::vector<int> &v) { 33 auto i = v.begin(); 34 35 clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}} 36 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 37 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin(){{$}}}} 38 39 if (i != v.begin()) { 40 clang_analyzer_warnIfReached(); 41 } 42 } 43 44 void end(const std::vector<int> &v) { 45 auto i = v.end(); 46 47 clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}} 48 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 49 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end(){{$}}}} 50 51 if (i != v.end()) { 52 clang_analyzer_warnIfReached(); 53 } 54 } 55 56 void prefix_increment(const std::vector<int> &v) { 57 auto i = v.begin(); 58 59 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 60 61 auto j = ++i; 62 63 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}} 64 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 1{{$}}}} 65 } 66 67 void prefix_decrement(const std::vector<int> &v) { 68 auto i = v.end(); 69 70 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 71 72 auto j = --i; 73 74 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}} 75 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 1{{$}}}} 76 } 77 78 void postfix_increment(const std::vector<int> &v) { 79 auto i = v.begin(); 80 81 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 82 83 auto j = i++; 84 85 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}} 86 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin(){{$}}}} 87 } 88 89 void postfix_decrement(const std::vector<int> &v) { 90 auto i = v.end(); 91 92 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 93 94 auto j = i--; 95 96 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}} 97 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end(){{$}}}} 98 } 99 100 void plus_equal(const std::vector<int> &v) { 101 auto i = v.begin(); 102 103 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 104 105 i += 2; 106 107 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 2{{$}}}} 108 } 109 110 void plus_equal_negative(const std::vector<int> &v) { 111 auto i = v.end(); 112 113 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 114 115 i += -2; 116 117 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 2{{$}}}} 118 } 119 120 void minus_equal(const std::vector<int> &v) { 121 auto i = v.end(); 122 123 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 124 125 i -= 2; 126 127 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 2{{$}}}} 128 } 129 130 void minus_equal_negative(const std::vector<int> &v) { 131 auto i = v.begin(); 132 133 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 134 135 i -= -2; 136 137 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 2{{$}}}} 138 } 139 140 void copy(const std::vector<int> &v) { 141 auto i1 = v.end(); 142 143 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 144 145 auto i2 = i1; 146 147 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} 148 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} 149 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end(){{$}}}} 150 } 151 152 void plus(const std::vector<int> &v) { 153 auto i1 = v.begin(); 154 155 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 156 157 auto i2 = i1 + 2; 158 159 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} 160 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re{{$v.begin(){{$}}}} 161 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re{{$v.begin() + 2{{$}}}} 162 } 163 164 void plus_negative(const std::vector<int> &v) { 165 auto i1 = v.end(); 166 167 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 168 169 auto i2 = i1 + (-2); 170 171 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} 172 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} 173 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}} 174 } 175 176 void minus(const std::vector<int> &v) { 177 auto i1 = v.end(); 178 179 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 180 181 auto i2 = i1 - 2; 182 183 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} 184 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} 185 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 2{{$}}}} 186 } 187 188 void minus_negative(const std::vector<int> &v) { 189 auto i1 = v.begin(); 190 191 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 192 193 auto i2 = i1 - (-2); 194 195 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}} 196 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}} 197 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin() + 2{{$}}}} 198 } 199 200 void copy_and_increment1(const std::vector<int> &v) { 201 auto i1 = v.begin(); 202 203 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 204 205 auto i2 = i1; 206 ++i1; 207 208 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin() + 1{{$}}}} 209 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin(){{$}}}} 210 } 211 212 void copy_and_increment2(const std::vector<int> &v) { 213 auto i1 = v.begin(); 214 215 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 216 217 auto i2 = i1; 218 ++i2; 219 220 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}} 221 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.begin() + 1{{$}}}} 222 } 223 224 void copy_and_decrement1(const std::vector<int> &v) { 225 auto i1 = v.end(); 226 227 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 228 229 auto i2 = i1; 230 --i1; 231 232 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end() - 1{{$}}}} 233 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end(){{$}}}} 234 } 235 236 void copy_and_decrement2(const std::vector<int> &v) { 237 auto i1 = v.end(); 238 239 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 240 241 auto i2 = i1; 242 --i2; 243 244 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}} 245 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$v.end() - 1{{$}}}} 246 } 247 248 /// std::advance(), std::prev(), std::next() 249 250 void std_advance_minus(const std::vector<int> &v) { 251 auto i = v.end(); 252 253 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 254 255 std::advance(i, -1); 256 257 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}} 258 } 259 260 void std_advance_plus(const std::vector<int> &v) { 261 auto i = v.begin(); 262 263 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 264 265 std::advance(i, 1); 266 267 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}} 268 } 269 270 void std_prev(const std::vector<int> &v) { 271 auto i = v.end(); 272 273 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 274 275 auto j = std::prev(i); 276 277 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 1{{$}}}} 278 } 279 280 void std_prev2(const std::vector<int> &v) { 281 auto i = v.end(); 282 283 clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()"); 284 285 auto j = std::prev(i, 2); 286 287 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.end() - 2{{$}}}} 288 } 289 290 void std_next(const std::vector<int> &v) { 291 auto i = v.begin(); 292 293 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 294 295 auto j = std::next(i); 296 297 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 1{{$}}}} 298 } 299 300 void std_next2(const std::vector<int> &v) { 301 auto i = v.begin(); 302 303 clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()"); 304 305 auto j = std::next(i, 2); 306 307 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning-re {{$v.begin() + 2{{$}}}} 308 } 309 310 //////////////////////////////////////////////////////////////////////////////// 311 /// 312 /// C O N T A I N E R A S S I G N M E N T S 313 /// 314 //////////////////////////////////////////////////////////////////////////////// 315 316 // Copy 317 318 void list_copy_assignment(std::list<int> &L1, const std::list<int> &L2) { 319 auto i0 = L1.cbegin(); 320 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 321 L1 = L2; 322 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 323 } 324 325 void vector_copy_assignment(std::vector<int> &V1, const std::vector<int> &V2) { 326 auto i0 = V1.cbegin(); 327 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 328 V1 = V2; 329 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 330 } 331 332 void deque_copy_assignment(std::deque<int> &D1, const std::deque<int> &D2) { 333 auto i0 = D1.cbegin(); 334 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 335 D1 = D2; 336 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 337 } 338 339 void forward_list_copy_assignment(std::forward_list<int> &FL1, 340 const std::forward_list<int> &FL2) { 341 auto i0 = FL1.cbegin(); 342 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 343 FL1 = FL2; 344 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 345 } 346 347 // Move 348 349 void list_move_assignment(std::list<int> &L1, std::list<int> &L2) { 350 auto i0 = L1.cbegin(), i1 = L2.cbegin(), i2 = --L2.cend(), i3 = L2.cend(); 351 352 clang_analyzer_denote(clang_analyzer_container_begin(L2), "$L2.begin()"); 353 clang_analyzer_denote(clang_analyzer_container_end(L2), "$L2.end()"); 354 355 L1 = std::move(L2); 356 357 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 358 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 359 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 360 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE. 361 362 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &L1); // expected-warning{{TRUE}} 363 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &L1); // expected-warning{{TRUE}} 364 365 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L2.begin(){{$}}}} 366 } 367 368 void vector_move_assignment(std::vector<int> &V1, std::vector<int> &V2) { 369 auto i0 = V1.cbegin(), i1 = V2.cbegin(), i2 = --V2.cend(), i3 = V2.cend(); 370 371 clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()"); 372 373 V1 = std::move(V2); 374 375 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 376 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 377 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 378 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE. 379 380 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &V1); // expected-warning{{TRUE}} 381 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &V1); // expected-warning{{TRUE}} 382 383 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V2.begin(){{$}}}} 384 } 385 386 void deque_move_assignment(std::deque<int> &D1, std::deque<int> &D2) { 387 auto i0 = D1.cbegin(), i1 = D2.cbegin(), i2 = --D2.cend(), i3 = D2.cend(); 388 389 clang_analyzer_denote(clang_analyzer_container_begin(D2), "$D2.begin()"); 390 391 D1 = std::move(D2); 392 393 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 394 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 395 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 396 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE. 397 398 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &D1); // expected-warning{{TRUE}} 399 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &D1); // expected-warning{{TRUE}} 400 401 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$D2.begin(){{$}}}} 402 } 403 404 void forward_list_move_assignment(std::forward_list<int> &FL1, 405 std::forward_list<int> &FL2) { 406 auto i0 = FL1.cbegin(), i1 = FL2.cbegin(), i2 = FL2.cend(); 407 408 clang_analyzer_denote(clang_analyzer_container_begin(FL2), "$FL2.begin()"); 409 410 FL1 = std::move(FL2); 411 412 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 413 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 414 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} FIXME: Should be FALSE. 415 416 clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &FL1); // expected-warning{{TRUE}} 417 418 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL2.begin(){{$}}}} 419 } 420 421 422 //////////////////////////////////////////////////////////////////////////////// 423 /// 424 /// C O N T A I N E R M O D I F I E R S 425 /// 426 //////////////////////////////////////////////////////////////////////////////// 427 428 /// assign() 429 /// 430 /// - Invalidates all iterators, including the past-the-end iterator for all 431 /// container types. 432 433 void list_assign(std::list<int> &L, int n) { 434 auto i0 = L.cbegin(), i1 = L.cend(); 435 L.assign(10, n); 436 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 437 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 438 } 439 440 void vector_assign(std::vector<int> &V, int n) { 441 auto i0 = V.cbegin(), i1 = V.cend(); 442 V.assign(10, n); 443 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 444 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 445 } 446 447 void deque_assign(std::deque<int> &D, int n) { 448 auto i0 = D.cbegin(), i1 = D.cend(); 449 D.assign(10, n); 450 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 451 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 452 } 453 454 void forward_list_assign(std::forward_list<int> &FL, int n) { 455 auto i0 = FL.cbegin(), i1 = FL.cend(); 456 FL.assign(10, n); 457 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 458 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 459 } 460 461 /// clear() 462 /// 463 /// - Invalidates all iterators, including the past-the-end iterator for all 464 /// container types. 465 466 void list_clear(std::list<int> &L) { 467 auto i0 = L.cbegin(), i1 = L.cend(); 468 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 469 L.clear(); 470 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 471 } 472 473 void vector_clear(std::vector<int> &V) { 474 auto i0 = V.cbegin(), i1 = V.cend(); 475 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 476 V.clear(); 477 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 478 } 479 480 void deque_clear(std::deque<int> &D) { 481 auto i0 = D.cbegin(), i1 = D.cend(); 482 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 483 D.clear(); 484 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 485 } 486 487 void forward_list_clear(std::forward_list<int> &FL) { 488 auto i0 = FL.cbegin(), i1 = FL.cend(); 489 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 490 FL.clear(); 491 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 492 } 493 494 /// push_back() 495 /// 496 /// - Design decision: extends containers to the ->RIGHT-> (i.e. the 497 /// past-the-end position of the container is incremented). 498 /// 499 /// - Iterator invalidation rules depend the container type. 500 501 /// std::list-like containers: No iterators are invalidated. 502 503 void list_push_back(std::list<int> &L, int n) { 504 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 505 506 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 507 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 508 509 L.push_back(n); 510 511 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 512 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 513 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 514 515 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 516 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} 517 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() + 1 518 } 519 520 /// std::vector-like containers: The past-the-end iterator is invalidated. 521 522 void vector_push_back(std::vector<int> &V, int n) { 523 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 524 525 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 526 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 527 528 V.push_back(n); 529 530 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 531 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 532 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 533 534 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 535 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} 536 } 537 538 /// std::deque-like containers: All iterators, including the past-the-end 539 /// iterator, are invalidated. 540 541 void deque_push_back(std::deque<int> &D, int n) { 542 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 543 544 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 545 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 546 547 D.push_back(n); 548 549 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 550 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 551 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 552 } 553 554 /// emplace_back() 555 /// 556 /// - Design decision: extends containers to the ->RIGHT-> (i.e. the 557 /// past-the-end position of the container is incremented). 558 /// 559 /// - Iterator invalidation rules depend the container type. 560 561 /// std::list-like containers: No iterators are invalidated. 562 563 void list_emplace_back(std::list<int> &L, int n) { 564 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 565 566 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 567 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 568 569 L.emplace_back(n); 570 571 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 572 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 573 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 574 575 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 576 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} 577 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() + 1 578 } 579 580 /// std::vector-like containers: The past-the-end iterator is invalidated. 581 582 void vector_emplace_back(std::vector<int> &V, int n) { 583 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 584 585 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 586 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 587 588 V.emplace_back(n); 589 590 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 591 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 592 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 593 594 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 595 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} 596 } 597 598 /// std::deque-like containers: All iterators, including the past-the-end 599 /// iterator, are invalidated. 600 601 void deque_emplace_back(std::deque<int> &D, int n) { 602 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 603 604 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 605 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 606 607 D.emplace_back(n); 608 609 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 610 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 611 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 612 } 613 614 /// pop_back() 615 /// 616 /// - Design decision: shrinks containers to the <-LEFT<- (i.e. the 617 /// past-the-end position of the container is decremented). 618 /// 619 /// - Iterator invalidation rules depend the container type. 620 621 /// std::list-like containers: Iterators to the last element are invalidated. 622 623 void list_pop_back(std::list<int> &L, int n) { 624 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 625 626 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 627 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 628 629 L.pop_back(); 630 631 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 632 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 633 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 634 635 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 636 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} FIXME: Should be $L.end() - 1 637 } 638 639 /// std::vector-like containers: Iterators to the last element, as well as the 640 /// past-the-end iterator, are invalidated. 641 642 void vector_pop_back(std::vector<int> &V, int n) { 643 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 644 645 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 646 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 647 648 V.pop_back(); 649 650 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 651 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 652 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 653 654 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 655 } 656 657 /// std::deque-like containers: Iterators to the last element are invalidated. 658 /// The past-the-end iterator is also invalidated. 659 /// Other iterators are not affected. 660 661 void deque_pop_back(std::deque<int> &D, int n) { 662 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 663 664 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 665 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 666 667 D.pop_back(); 668 669 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 670 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 671 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 672 673 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$D.begin(){{$}}}} 674 } 675 676 /// push_front() 677 /// 678 /// - Design decision: extends containers to the <-LEFT<- (i.e. the first 679 /// position of the container is decremented). 680 /// 681 /// - Iterator invalidation rules depend the container type. 682 683 /// std::list-like containers: No iterators are invalidated. 684 685 void list_push_front(std::list<int> &L, int n) { 686 auto i0 = L.cbegin(), i1 = L.cend(); 687 688 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 689 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 690 691 L.push_front(n); 692 693 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 694 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 695 696 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 697 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} 698 } 699 700 /// std::deque-like containers: All iterators, including the past-the-end 701 /// iterator, are invalidated. 702 703 void deque_push_front(std::deque<int> &D, int n) { 704 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 705 706 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 707 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 708 709 D.push_front(n); 710 711 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 712 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 713 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 714 } 715 716 /// std::forward_list-like containers: No iterators are invalidated. 717 718 void forward_list_push_front(std::forward_list<int> &FL, int n) { 719 auto i0 = FL.cbegin(), i1 = FL.cend(); 720 721 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 722 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 723 724 FL.push_front(n); 725 726 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 727 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 728 729 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 730 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} 731 } 732 733 /// emplace_front() 734 /// 735 /// - Design decision: extends containers to the <-LEFT<- (i.e. the first 736 /// position of the container is decremented). 737 /// 738 /// - Iterator invalidation rules depend the container type. 739 740 /// std::list-like containers: No iterators are invalidated. 741 742 void list_emplace_front(std::list<int> &L, int n) { 743 auto i0 = L.cbegin(), i1 = L.cend(); 744 745 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 746 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 747 748 L.emplace_front(n); 749 750 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 751 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 752 753 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 754 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} 755 } 756 757 /// std::deque-like containers: All iterators, including the past-the-end 758 /// iterator, are invalidated. 759 760 void deque_emplace_front(std::deque<int> &D, int n) { 761 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 762 763 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 764 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 765 766 D.emplace_front(n); 767 768 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 769 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 770 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 771 } 772 773 /// std::forward_list-like containers: No iterators are invalidated. 774 775 void forward_list_emplace_front(std::forward_list<int> &FL, int n) { 776 auto i0 = FL.cbegin(), i1 = FL.cend(); 777 778 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 779 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 780 781 FL.emplace_front(n); 782 783 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 784 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 785 786 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 787 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} 788 } 789 790 /// pop_front() 791 /// 792 /// - Design decision: shrinks containers to the ->RIGHT-> (i.e. the first 793 /// position of the container is incremented). 794 /// 795 /// - Iterator invalidation rules depend the container type. 796 797 /// std::list-like containers: Iterators to the first element are invalidated. 798 799 void list_pop_front(std::list<int> &L, int n) { 800 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); 801 802 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 803 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 804 805 L.pop_front(); 806 807 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 808 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 809 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 810 811 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} 812 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 813 } 814 815 /// std::deque-like containers: Iterators to the first element are invalidated. 816 /// Other iterators are not affected. 817 818 void deque_pop_front(std::deque<int> &D, int n) { 819 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); 820 821 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 822 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 823 824 D.pop_front(); 825 826 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 827 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 828 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 829 830 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$D.begin() + 1{{$}}}} 831 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$D.end(){{$}}}} 832 } 833 834 /// std::forward_list-like containers: Iterators to the first element are 835 /// invalidated. 836 837 void forward_list_pop_front(std::list<int> &FL, int n) { 838 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend(); 839 840 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 841 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 842 843 FL.pop_front(); 844 845 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 846 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 847 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 848 849 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}} 850 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} 851 } 852 853 /// insert() 854 /// 855 /// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator 856 /// ahead of the insertion point are decremented; if the 857 /// relation between the insertion point and the first 858 /// position of the container is known, the first position 859 /// of the container is also decremented). 860 /// 861 /// - Iterator invalidation rules depend the container type. 862 863 /// std::list-like containers: No iterators are invalidated. 864 865 void list_insert_begin(std::list<int> &L, int n) { 866 auto i0 = L.cbegin(), i1 = L.cend(); 867 868 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 869 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 870 871 auto i2 = L.insert(i0, n); 872 873 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 874 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 875 876 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 877 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1 878 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} 879 } 880 881 void list_insert_behind_begin(std::list<int> &L, int n) { 882 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); 883 884 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 885 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 886 887 auto i3 = L.insert(i1, n); 888 889 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 890 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 891 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 892 893 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1 894 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} 895 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() 896 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 897 } 898 899 template <typename Iter> Iter return_any_iterator(const Iter &It); 900 901 void list_insert_unknown(std::list<int> &L, int n) { 902 auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend(); 903 904 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 905 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 906 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 907 908 auto i3 = L.insert(i1, n); 909 910 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 911 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 912 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 913 914 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 915 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} 916 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1 917 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 918 } 919 920 void list_insert_ahead_of_end(std::list<int> &L, int n) { 921 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 922 923 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 924 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 925 926 auto i3 = L.insert(i1, n); 927 928 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 929 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 930 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 931 932 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 933 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} 934 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 935 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2 936 } 937 938 void list_insert_end(std::list<int> &L, int n) { 939 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 940 941 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 942 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 943 944 auto i3 = L.insert(i2, n); 945 946 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 947 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 948 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 949 950 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 951 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2 952 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 953 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1 954 } 955 956 /// std::vector-like containers: Only the iterators before the insertion point 957 /// remain valid. The past-the-end iterator is also 958 /// invalidated. 959 960 void vector_insert_begin(std::vector<int> &V, int n) { 961 auto i0 = V.cbegin(), i1 = V.cend(); 962 963 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 964 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 965 966 auto i2 = V.insert(i0, n); 967 968 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 969 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 970 971 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1 972 } 973 974 void vector_insert_behind_begin(std::vector<int> &V, int n) { 975 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); 976 977 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 978 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 979 980 auto i3 = V.insert(i1, n); 981 982 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 983 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 984 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 985 986 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() - 1 987 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin() 988 } 989 990 void vector_insert_unknown(std::vector<int> &V, int n) { 991 auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend(); 992 993 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 994 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 995 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 996 997 auto i3 = V.insert(i1, n); 998 999 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1000 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1001 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1002 1003 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1004 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1 1005 } 1006 1007 void vector_insert_ahead_of_end(std::vector<int> &V, int n) { 1008 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 1009 1010 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1011 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1012 1013 auto i3 = V.insert(i1, n); 1014 1015 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1016 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1017 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1018 1019 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1020 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2 1021 } 1022 1023 void vector_insert_end(std::vector<int> &V, int n) { 1024 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 1025 1026 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1027 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1028 1029 auto i3 = V.insert(i2, n); 1030 1031 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1032 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1033 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1034 1035 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1036 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} FIXME: Should be $V.end() - 2 1037 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1 1038 } 1039 1040 /// std::deque-like containers: All iterators, including the past-the-end 1041 /// iterator, are invalidated. 1042 1043 void deque_insert_begin(std::deque<int> &D, int n) { 1044 auto i0 = D.cbegin(), i1 = D.cend(); 1045 1046 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1047 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1048 1049 auto i2 = D.insert(i0, n); 1050 1051 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1052 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1053 1054 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1 1055 } 1056 1057 void deque_insert_behind_begin(std::deque<int> &D, int n) { 1058 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); 1059 1060 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1061 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1062 1063 auto i3 = D.insert(i1, n); 1064 1065 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1066 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1067 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1068 1069 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1 1070 } 1071 1072 void deque_insert_unknown(std::deque<int> &D, int n) { 1073 auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend(); 1074 1075 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1076 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1077 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1078 1079 auto i3 = D.insert(i1, n); 1080 1081 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1082 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1083 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1084 1085 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1 1086 } 1087 1088 void deque_insert_ahead_of_end(std::deque<int> &D, int n) { 1089 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 1090 1091 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1092 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1093 1094 auto i3 = D.insert(i1, n); 1095 1096 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1097 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1098 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1099 1100 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2 1101 } 1102 1103 void deque_insert_end(std::deque<int> &D, int n) { 1104 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 1105 1106 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1107 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1108 1109 auto i3 = D.insert(i2, n); 1110 1111 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1112 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1113 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1114 1115 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1 1116 } 1117 1118 /// insert_after() [std::forward_list-like containers] 1119 /// 1120 /// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator 1121 /// ahead of the insertion point are incremented; if the 1122 /// relation between the insertion point and the past-the-end 1123 /// position of the container is known, the first position of 1124 /// the container is also incremented). 1125 /// 1126 /// - No iterators are invalidated. 1127 1128 void forward_list_insert_after_begin(std::forward_list<int> &FL, int n) { 1129 auto i0 = FL.cbegin(), i1 = FL.cend(); 1130 1131 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1132 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1133 1134 auto i2 = FL.insert_after(i0, n); 1135 1136 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1137 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1138 1139 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1140 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1 1141 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} 1142 } 1143 1144 void forward_list_insert_after_behind_begin(std::forward_list<int> &FL, int n) { 1145 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend(); 1146 1147 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1148 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1149 1150 auto i3 = FL.insert_after(i1, n); 1151 1152 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1153 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1154 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1155 1156 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1157 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}} 1158 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2 1159 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} 1160 } 1161 1162 void forward_list_insert_after_unknown(std::forward_list<int> &FL, int n) { 1163 auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = FL.cend(); 1164 1165 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1166 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1167 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1168 1169 auto i3 = FL.insert_after(i1, n); 1170 1171 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1172 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1173 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1174 1175 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1176 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} 1177 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 1178 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} 1179 } 1180 1181 /// emplace() 1182 /// 1183 /// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator 1184 /// ahead of the emplacement point are decremented; if the 1185 /// relation between the emplacement point and the first 1186 /// position of the container is known, the first position 1187 /// of the container is also decremented). 1188 /// 1189 /// - Iterator invalidation rules depend the container type. 1190 1191 /// std::list-like containers: No iterators are invalidated. 1192 1193 void list_emplace_begin(std::list<int> &L, int n) { 1194 auto i0 = L.cbegin(), i1 = L.cend(); 1195 1196 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1197 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1198 1199 auto i2 = L.emplace(i0, n); 1200 1201 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1202 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1203 1204 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 1205 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1 1206 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end(){{$}}}} 1207 } 1208 1209 void list_emplace_behind_begin(std::list<int> &L, int n) { 1210 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); 1211 1212 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1213 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1214 1215 auto i3 = L.emplace(i1, n); 1216 1217 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1218 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1219 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1220 1221 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1 1222 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} 1223 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() 1224 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1225 } 1226 1227 template <typename Iter> Iter return_any_iterator(const Iter &It); 1228 1229 void list_emplace_unknown(std::list<int> &L, int n) { 1230 auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend(); 1231 1232 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1233 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1234 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1235 1236 auto i3 = L.emplace(i1, n); 1237 1238 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1239 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1240 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1241 1242 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 1243 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} 1244 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1 1245 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1246 } 1247 1248 void list_emplace_ahead_of_end(std::list<int> &L, int n) { 1249 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 1250 1251 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1252 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1253 1254 auto i3 = L.emplace(i1, n); 1255 1256 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1257 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1258 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1259 1260 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 1261 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} 1262 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1263 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2 1264 } 1265 1266 void list_emplace_end(std::list<int> &L, int n) { 1267 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 1268 1269 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1270 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1271 1272 auto i3 = L.emplace(i2, n); 1273 1274 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1275 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1276 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1277 1278 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 1279 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2 1280 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1281 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1 1282 } 1283 1284 /// std::vector-like containers: Only the iterators before the emplacement point 1285 /// remain valid. The past-the-end iterator is also 1286 /// invalidated. 1287 1288 void vector_emplace_begin(std::vector<int> &V, int n) { 1289 auto i0 = V.cbegin(), i1 = V.cend(); 1290 1291 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1292 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1293 1294 auto i2 = V.emplace(i0, n); 1295 1296 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1297 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1298 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1 1299 } 1300 1301 void vector_emplace_behind_begin(std::vector<int> &V, int n) { 1302 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); 1303 1304 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1305 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1306 1307 auto i3 = V.emplace(i1, n); 1308 1309 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1310 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1311 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1312 1313 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() - 1 1314 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin() 1315 } 1316 1317 void vector_emplace_unknown(std::vector<int> &V, int n) { 1318 auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend(); 1319 1320 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1321 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1322 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1323 1324 auto i3 = V.emplace(i1, n); 1325 1326 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1327 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1328 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1329 1330 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1331 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1 1332 } 1333 1334 void vector_emplace_ahead_of_end(std::vector<int> &V, int n) { 1335 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 1336 1337 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1338 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1339 1340 auto i3 = V.emplace(i1, n); 1341 1342 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1343 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1344 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1345 1346 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1347 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2 1348 } 1349 1350 void vector_emplace_end(std::vector<int> &V, int n) { 1351 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 1352 1353 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1354 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1355 1356 auto i3 = V.emplace(i2, n); 1357 1358 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1359 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1360 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1361 1362 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1363 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$V.end() - 1{{$}}}} FIXME: Should be $V.end() - 2 1364 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1 1365 } 1366 1367 /// std::deque-like containers: All iterators, including the past-the-end 1368 /// iterator, are invalidated. 1369 1370 void deque_emplace_begin(std::deque<int> &D, int n) { 1371 auto i0 = D.cbegin(), i1 = D.cend(); 1372 1373 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1374 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1375 1376 auto i2 = D.emplace(i0, n); 1377 1378 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1379 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1380 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1 1381 } 1382 1383 void deque_emplace_behind_begin(std::deque<int> &D, int n) { 1384 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); 1385 1386 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1387 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1388 1389 auto i3 = D.emplace(i1, n); 1390 1391 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1392 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1393 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1394 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1 1395 } 1396 1397 void deque_emplace_unknown(std::deque<int> &D, int n) { 1398 auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend(); 1399 1400 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1401 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1402 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1403 1404 auto i3 = D.emplace(i1, n); 1405 1406 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1407 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1408 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1409 1410 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1 1411 } 1412 1413 void deque_emplace_ahead_of_end(std::deque<int> &D, int n) { 1414 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 1415 1416 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1417 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1418 1419 auto i3 = D.emplace(i1, n); 1420 1421 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1422 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1423 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1424 1425 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2 1426 } 1427 1428 void deque_emplace_end(std::deque<int> &D, int n) { 1429 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 1430 1431 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1432 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1433 1434 auto i3 = D.emplace(i2, n); 1435 1436 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1437 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1438 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1439 1440 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1 1441 } 1442 1443 /// emplace_after() [std::forward_list-like containers] 1444 /// 1445 /// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator 1446 /// ahead of the emplacement point are incremented; if the 1447 /// relation between the emplacement point and the 1448 /// past-the-end position of the container is known, the 1449 /// first position of the container is also incremented). 1450 /// 1451 /// - No iterators are invalidated. 1452 1453 void forward_list_emplace_after_begin(std::forward_list<int> &FL, int n) { 1454 auto i0 = FL.cbegin(), i1 = FL.cend(); 1455 1456 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1457 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1458 1459 auto i2 = FL.emplace_after(i0, n); 1460 1461 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1462 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1463 1464 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1465 // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1 1466 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.end(){{$}}}} 1467 } 1468 1469 void forward_list_emplace_after_behind_begin(std::forward_list<int> &FL, 1470 int n) { 1471 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend(); 1472 1473 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1474 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1475 1476 auto i3 = FL.emplace_after(i1, n); 1477 1478 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1479 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1480 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1481 1482 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1483 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$FL.begin() + 1{{$}}}} 1484 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2 1485 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} 1486 } 1487 1488 void forward_list_emplace_after_unknown(std::forward_list<int> &FL, int n) { 1489 auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = FL.cend(); 1490 1491 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1492 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1493 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1494 1495 auto i3 = FL.emplace_after(i1, n); 1496 1497 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1498 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1499 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1500 1501 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1502 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} 1503 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 1504 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}} 1505 } 1506 1507 /// erase() 1508 /// 1509 /// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator 1510 /// ahead of the ereased element are incremented; if the 1511 /// relation between the position of the erased element 1512 /// and the first position of the container is known, the 1513 /// first position of the container is also incremented). 1514 /// 1515 /// - Iterator invalidation rules depend the container type. 1516 1517 /// std::list-like containers: Iterators to the erased element are invalidated. 1518 /// Other iterators are not affected. 1519 1520 void list_erase_begin(std::list<int> &L) { 1521 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); 1522 1523 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1524 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1525 1526 auto i3 = L.erase(i0); 1527 1528 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1529 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1530 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1531 1532 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}} 1533 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 1 1534 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1535 } 1536 1537 void list_erase_behind_begin(std::list<int> &L, int n) { 1538 auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend(); 1539 1540 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1541 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1542 1543 auto i3 = L.erase(i1); 1544 1545 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1546 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1547 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1548 1549 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() + 1 1550 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 2 1551 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1552 } 1553 1554 void list_erase_unknown(std::list<int> &L) { 1555 auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend(); 1556 1557 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1558 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1559 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1560 1561 auto i3 = L.erase(i1); 1562 1563 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1564 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1565 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1566 1567 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 1568 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 1569 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1570 } 1571 1572 void list_erase_ahead_of_end(std::list<int> &L) { 1573 auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend(); 1574 1575 clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()"); 1576 clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()"); 1577 1578 auto i3 = L.erase(i1); 1579 1580 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1581 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1582 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1583 1584 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}} 1585 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}} 1586 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() 1587 } 1588 1589 /// std::vector-like containers: Invalidates iterators at or after the point of 1590 /// the erase, including the past-the-end iterator. 1591 1592 void vector_erase_begin(std::vector<int> &V) { 1593 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); 1594 1595 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1596 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1597 1598 auto i3 = V.erase(i0); 1599 1600 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1601 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1602 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1603 1604 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 1 1605 } 1606 1607 void vector_erase_behind_begin(std::vector<int> &V, int n) { 1608 auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend(); 1609 1610 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1611 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1612 1613 auto i3 = V.erase(i1); 1614 1615 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1616 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1617 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1618 1619 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} FIXME: Should be $V.begin() + 1 1620 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 2 1621 } 1622 1623 void vector_erase_unknown(std::vector<int> &V) { 1624 auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend(); 1625 1626 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1627 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1628 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1629 1630 auto i3 = V.erase(i1); 1631 1632 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1633 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1634 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1635 1636 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1637 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 1638 } 1639 1640 void vector_erase_ahead_of_end(std::vector<int> &V) { 1641 auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend(); 1642 1643 clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()"); 1644 clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()"); 1645 1646 auto i3 = V.erase(i1); 1647 1648 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1649 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1650 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1651 1652 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}} 1653 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() 1654 } 1655 1656 /// std::deque-like containers: All iterators are invalidated, unless the erased 1657 /// element is at the end or the beginning of the 1658 /// container, in which case only the iterators to 1659 /// the erased element are invalidated. The 1660 /// past-the-end iterator is also invalidated unless 1661 /// the erased element is at the beginning of the 1662 /// container and the last element is not erased. 1663 1664 void deque_erase_begin(std::deque<int> &D) { 1665 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); 1666 1667 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1668 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1669 1670 auto i3 = D.erase(i0); 1671 1672 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1673 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1674 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1675 1676 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 1 1677 } 1678 1679 void deque_erase_behind_begin(std::deque<int> &D, int n) { 1680 auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend(); 1681 1682 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1683 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1684 1685 auto i3 = D.erase(i1); 1686 1687 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1688 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1689 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1690 1691 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 2 1692 } 1693 1694 void deque_erase_unknown(std::deque<int> &D) { 1695 auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend(); 1696 1697 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1698 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1699 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1700 1701 auto i3 = D.erase(i1); 1702 1703 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1704 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1705 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1706 1707 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1 1708 } 1709 1710 void deque_erase_ahead_of_end(std::deque<int> &D) { 1711 auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend(); 1712 1713 clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()"); 1714 clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()"); 1715 1716 auto i3 = D.erase(i1); 1717 1718 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}} 1719 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1720 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1721 1722 // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() 1723 } 1724 1725 /// erase_after() [std::forward_list-like containers] 1726 /// 1727 /// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator 1728 /// begind of the ereased element are decremented; if the 1729 /// relation between the position of the erased element 1730 /// and the past-the-end position of the container is known, 1731 /// the past-the-end position of the container is also 1732 /// decremented). 1733 /// 1734 /// - Iterators to the erased element are invalidated. Other iterators are not 1735 /// affected. 1736 1737 1738 void forward_list_erase_after_begin(std::forward_list<int> &FL) { 1739 auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = i1, i3 = FL.cend(); 1740 ++i2; 1741 1742 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1743 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1744 1745 auto i4 = FL.erase_after(i0); 1746 1747 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1748 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}} 1749 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} 1750 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} 1751 1752 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1753 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.begin() + 2{{$}}}} FIXME: Should be $FL.begin() + 1 1754 // clang_analyzer_express(clang_analyzer_iterator_position(i4)); FIXME: expect warning $FL.begin() + 1 1755 clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$FL.end(){{$}}}} 1756 } 1757 1758 void forward_list_erase_after_unknown(std::forward_list<int> &FL) { 1759 auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = i1, 1760 i3 = i1, i4 = FL.cend(); 1761 ++i2; 1762 ++i3; 1763 ++i3; 1764 1765 clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()"); 1766 clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()"); 1767 clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); 1768 1769 auto i5 = FL.erase_after(i1); 1770 1771 clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} 1772 clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} 1773 clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}} 1774 clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} 1775 clang_analyzer_eval(clang_analyzer_iterator_validity(i4)); //expected-warning{{TRUE}} 1776 1777 clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}} 1778 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}} 1779 clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$i1 + 2{{$}}}} FIXME: Should be $i1 + 1 1780 // clang_analyzer_express(clang_analyzer_iterator_position(i5)); FIXME: expect warning $i1 + 1 1781 clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning-re {{$FL.end(){{$}}}} 1782 } 1783 1784 struct simple_iterator_base { 1785 simple_iterator_base(); 1786 simple_iterator_base(const simple_iterator_base& rhs); 1787 simple_iterator_base &operator=(const simple_iterator_base& rhs); 1788 virtual ~simple_iterator_base(); 1789 bool friend operator==(const simple_iterator_base &lhs, 1790 const simple_iterator_base &rhs); 1791 bool friend operator!=(const simple_iterator_base &lhs, 1792 const simple_iterator_base &rhs); 1793 private: 1794 int *ptr; 1795 }; 1796 1797 struct simple_derived_iterator: public simple_iterator_base { 1798 int& operator*(); 1799 int* operator->(); 1800 simple_iterator_base &operator++(); 1801 simple_iterator_base operator++(int); 1802 simple_iterator_base &operator--(); 1803 simple_iterator_base operator--(int); 1804 }; 1805 1806 struct simple_container { 1807 typedef simple_derived_iterator iterator; 1808 1809 iterator begin(); 1810 iterator end(); 1811 }; 1812 1813 void good_derived(simple_container c) { 1814 auto i0 = c.end(); 1815 1816 if (i0 != c.end()) { 1817 clang_analyzer_warnIfReached(); 1818 } 1819 } 1820 1821 void iter_diff(std::vector<int> &V) { 1822 auto i0 = V.begin(), i1 = V.end(); 1823 ptrdiff_t len = i1 - i0; // no-crash 1824 } 1825 1826 void deferred_assumption(std::vector<int> &V, int e) { 1827 const auto first = V.begin(); 1828 const auto comp1 = (first != V.end()), comp2 = (first == V.end()); 1829 if (comp1) { 1830 clang_analyzer_eval(clang_analyzer_container_end(V) == 1831 clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} 1832 } 1833 } 1834 1835 void loop(std::vector<int> &V, int e) { 1836 auto start = V.begin(); 1837 while (true) { 1838 auto item = std::find(start, V.end(), e); 1839 if (item == V.end()) 1840 break; 1841 1842 clang_analyzer_eval(clang_analyzer_container_end(V) == 1843 clang_analyzer_iterator_position(item)); // expected-warning@-1{{FALSE}} 1844 } 1845 } 1846 1847 template <typename InputIterator, typename T> 1848 InputIterator nonStdFind(InputIterator first, InputIterator last, 1849 const T &val) { 1850 for (auto i = first; i != last; ++i) { 1851 if (*i == val) { 1852 return i; 1853 } 1854 } 1855 return last; 1856 } 1857 1858 void non_std_find(std::vector<int> &V, int e) { 1859 auto first = nonStdFind(V.begin(), V.end(), e); 1860 clang_analyzer_eval(clang_analyzer_container_end(V) == 1861 clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} expected-warning@-1{{TRUE}} 1862 if (V.end() != first) { 1863 clang_analyzer_eval(clang_analyzer_container_end(V) == 1864 clang_analyzer_iterator_position(first)); // expected-warning@-1{{FALSE}} 1865 } 1866 } 1867 1868 template<typename T> 1869 struct cont_with_ptr_iterator { 1870 typedef T* iterator; 1871 T* begin() const; 1872 T* end() const; 1873 }; 1874 1875 void begin_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1876 auto i = c.begin(); 1877 1878 clang_analyzer_eval(clang_analyzer_iterator_container(i) == &c); // expected-warning{{TRUE}} 1879 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); 1880 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin()}} 1881 1882 if (i != c.begin()) { 1883 clang_analyzer_warnIfReached(); 1884 } 1885 } 1886 1887 void prefix_increment_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1888 auto i = c.begin(); 1889 1890 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); 1891 1892 auto j = ++i; 1893 1894 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 1}} 1895 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.begin() + 1}} 1896 } 1897 1898 void prefix_decrement_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1899 auto i = c.end(); 1900 1901 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); 1902 1903 auto j = --i; 1904 1905 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 1}} 1906 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.end() - 1}} 1907 } 1908 1909 void postfix_increment_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1910 auto i = c.begin(); 1911 1912 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); 1913 1914 auto j = i++; 1915 1916 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 1}} 1917 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.begin()}} 1918 } 1919 1920 void postfix_decrement_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1921 auto i = c.end(); 1922 1923 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); 1924 1925 auto j = i--; 1926 1927 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 1}} 1928 clang_analyzer_express(clang_analyzer_iterator_position(j)); // expected-warning{{$c.end()}} 1929 } 1930 1931 void plus_equal_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1932 auto i = c.begin(); 1933 1934 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); 1935 1936 i += 2; 1937 1938 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.begin() + 2}} 1939 } 1940 1941 void minus_equal_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1942 auto i = c.end(); 1943 1944 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); 1945 1946 i -= 2; 1947 1948 clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$c.end() - 2}} 1949 } 1950 1951 void minus_equal_ptr_iterator_variable(const cont_with_ptr_iterator<int> &c, 1952 int n) { 1953 auto i = c.end(); 1954 1955 i -= n; // no-crash 1956 } 1957 1958 void plus_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1959 auto i1 = c.begin(); 1960 1961 clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()"); 1962 1963 auto i2 = i1 + 2; 1964 1965 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}} 1966 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.begin()}} 1967 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.begin() + 2}} 1968 } 1969 1970 void minus_ptr_iterator(const cont_with_ptr_iterator<int> &c) { 1971 auto i1 = c.end(); 1972 1973 clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()"); 1974 1975 auto i2 = i1 - 2; 1976 1977 clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}} 1978 clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$c.end()}} 1979 clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.end() - 2}} 1980 } 1981 1982 void ptr_iter_diff(cont_with_ptr_iterator<int> &c) { 1983 auto i0 = c.begin(), i1 = c.end(); 1984 ptrdiff_t len = i1 - i0; // no-crash 1985 } 1986 1987 void ptr_iter_cmp_nullptr(cont_with_ptr_iterator<int> &c) { 1988 auto i0 = c.begin(); 1989 if (i0 != nullptr) // no-crash 1990 ++i0; 1991 } 1992 1993 void clang_analyzer_printState(); 1994 1995 void print_state(std::vector<int> &V) { 1996 const auto i0 = V.cbegin(); 1997 clang_analyzer_printState(); 1998 1999 // CHECK: "checker_messages": [ 2000 // CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [ 2001 // CHECK-NEXT: "Iterator Positions :", 2002 // CHECK-NEXT: "i0 : Valid ; Container == SymRegion{reg_$[[#]]<std::vector<int> & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}" 2003 // CHECK-NEXT: ]} 2004 2005 *i0; 2006 const auto i1 = V.cend(); 2007 clang_analyzer_printState(); 2008 2009 // CHECK: "checker_messages": [ 2010 // CHECK: { "checker": "alpha.cplusplus.IteratorModeling", "messages": [ 2011 // CHECK-NEXT: "Iterator Positions :", 2012 // CHECK-NEXT: "i1 : Valid ; Container == SymRegion{reg_$[[#]]<std::vector<int> & V>} ; Offset == conj_$[[#]]{long, LC[[#]], S[[#]], #[[#]]}" 2013 // CHECK-NEXT: ]} 2014 2015 *i1; 2016 } 2017