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