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