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