1// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DI386 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -analyzer-config eagerly-assume=false %s 2// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DI386 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -DTEST_INLINABLE_ALLOCATORS -analyzer-config eagerly-assume=false %s 3// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin12 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -analyzer-config eagerly-assume=false %s 4// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin12 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify -DTEST_INLINABLE_ALLOCATORS -analyzer-config eagerly-assume=false %s 5 6#include "Inputs/system-header-simulator-cxx.h" 7 8void clang_analyzer_eval(bool); 9void clang_analyzer_checkInlined(bool); 10 11// A simplified version of std::move. 12template <typename T> 13T &&move(T &obj) { 14 return static_cast<T &&>(obj); 15} 16 17 18struct Wrapper { 19 __strong id obj; 20}; 21 22void test() { 23 Wrapper w; 24 // force a diagnostic 25 *(char *)0 = 1; // expected-warning{{Dereference of null pointer}} 26} 27 28 29struct IntWrapper { 30 int x; 31}; 32 33void testCopyConstructor() { 34 IntWrapper a; 35 a.x = 42; 36 37 IntWrapper b(a); 38 clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}} 39} 40 41struct NonPODIntWrapper { 42 int x; 43 44 virtual int get(); 45}; 46 47void testNonPODCopyConstructor() { 48 NonPODIntWrapper a; 49 a.x = 42; 50 51 NonPODIntWrapper b(a); 52 clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}} 53} 54 55 56namespace ConstructorVirtualCalls { 57 class A { 58 public: 59 int *out1, *out2, *out3; 60 61 virtual int get() { return 1; } 62 63 A(int *out1) { 64 *out1 = get(); 65 } 66 }; 67 68 class B : public A { 69 public: 70 virtual int get() { return 2; } 71 72 B(int *out1, int *out2) : A(out1) { 73 *out2 = get(); 74 } 75 }; 76 77 class C : public B { 78 public: 79 virtual int get() { return 3; } 80 81 C(int *out1, int *out2, int *out3) : B(out1, out2) { 82 *out3 = get(); 83 } 84 }; 85 86 void test() { 87 int a, b, c; 88 89 C obj(&a, &b, &c); 90 clang_analyzer_eval(a == 1); // expected-warning{{TRUE}} 91 clang_analyzer_eval(b == 2); // expected-warning{{TRUE}} 92 clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} 93 94 clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}} 95 96 // Sanity check for devirtualization. 97 A *base = &obj; 98 clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}} 99 } 100} 101 102namespace TemporaryConstructor { 103 class BoolWrapper { 104 public: 105 BoolWrapper() { 106 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} 107 value = true; 108 } 109 bool value; 110 }; 111 112 void test() { 113 // PR13717 - Don't crash when a CXXTemporaryObjectExpr is inlined. 114 if (BoolWrapper().value) 115 return; 116 } 117} 118 119 120namespace ConstructorUsedAsRValue { 121 using TemporaryConstructor::BoolWrapper; 122 123 bool extractValue(BoolWrapper b) { 124 return b.value; 125 } 126 127 void test() { 128 bool result = extractValue(BoolWrapper()); 129 clang_analyzer_eval(result); // expected-warning{{TRUE}} 130 } 131} 132 133namespace PODUninitialized { 134 class POD { 135 public: 136 int x, y; 137 }; 138 139 class PODWrapper { 140 public: 141 POD p; 142 }; 143 144 class NonPOD { 145 public: 146 int x, y; 147 148 NonPOD() {} 149 NonPOD(const NonPOD &Other) 150 : x(Other.x), y(Other.y) // expected-warning {{undefined}} 151 { 152 } 153 NonPOD(NonPOD &&Other) 154 : x(Other.x), y(Other.y) // expected-warning {{undefined}} 155 { 156 } 157 158 NonPOD &operator=(const NonPOD &Other) 159 { 160 x = Other.x; 161 y = Other.y; // expected-warning {{undefined}} 162 return *this; 163 } 164 NonPOD &operator=(NonPOD &&Other) 165 { 166 x = Other.x; 167 y = Other.y; // expected-warning {{undefined}} 168 return *this; 169 } 170 }; 171 172 class NonPODWrapper { 173 public: 174 class Inner { 175 public: 176 int x, y; 177 178 Inner() {} 179 Inner(const Inner &Other) 180 : x(Other.x), y(Other.y) // expected-warning {{undefined}} 181 { 182 } 183 Inner(Inner &&Other) 184 : x(Other.x), y(Other.y) // expected-warning {{undefined}} 185 { 186 } 187 188 Inner &operator=(const Inner &Other) 189 { 190 x = Other.x; // expected-warning {{undefined}} 191 y = Other.y; 192 return *this; 193 } 194 Inner &operator=(Inner &&Other) 195 { 196 x = Other.x; // expected-warning {{undefined}} 197 y = Other.y; 198 return *this; 199 } 200 }; 201 202 Inner p; 203 }; 204 205 void testPOD(const POD &pp) { 206 POD p; 207 p.x = 1; 208 POD p2 = p; // no-warning 209 clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}} 210 POD p3 = move(p); // no-warning 211 clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}} 212 213 // Use rvalues as well. 214 clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}} 215 216 // Copy from symbolic references correctly. 217 POD p4 = pp; 218 // Make sure that p4.x contains a symbol after copy. 219 if (p4.x > 0) 220 clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}} 221 // FIXME: Element region gets in the way, so these aren't the same symbols 222 // as they should be. 223 clang_analyzer_eval(pp.x == p4.x); // expected-warning{{UNKNOWN}} 224 225 PODWrapper w; 226 w.p.y = 1; 227 PODWrapper w2 = w; // no-warning 228 clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}} 229 PODWrapper w3 = move(w); // no-warning 230 clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}} 231 232 // Use rvalues as well. 233 clang_analyzer_eval(PODWrapper(w3).p.y == 1); // expected-warning{{TRUE}} 234 } 235 236 void testNonPOD() { 237 NonPOD p; 238 p.x = 1; 239 NonPOD p2 = p; 240 } 241 242 void testNonPODMove() { 243 NonPOD p; 244 p.x = 1; 245 NonPOD p2 = move(p); 246 } 247 248 void testNonPODWrapper() { 249 NonPODWrapper w; 250 w.p.y = 1; 251 NonPODWrapper w2 = w; 252 } 253 254 void testNonPODWrapperMove() { 255 NonPODWrapper w; 256 w.p.y = 1; 257 NonPODWrapper w2 = move(w); 258 } 259 260 // Not strictly about constructors, but trivial assignment operators should 261 // essentially work the same way. 262 namespace AssignmentOperator { 263 void testPOD() { 264 POD p; 265 p.x = 1; 266 POD p2; 267 p2 = p; // no-warning 268 clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}} 269 POD p3; 270 p3 = move(p); // no-warning 271 clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}} 272 273 PODWrapper w; 274 w.p.y = 1; 275 PODWrapper w2; 276 w2 = w; // no-warning 277 clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}} 278 PODWrapper w3; 279 w3 = move(w); // no-warning 280 clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}} 281 } 282 283 void testReturnValue() { 284 POD p; 285 p.x = 1; 286 POD p2; 287 clang_analyzer_eval(&(p2 = p) == &p2); // expected-warning{{TRUE}} 288 289 PODWrapper w; 290 w.p.y = 1; 291 PODWrapper w2; 292 clang_analyzer_eval(&(w2 = w) == &w2); // expected-warning{{TRUE}} 293 } 294 295 void testNonPOD() { 296 NonPOD p; 297 p.x = 1; 298 NonPOD p2; 299 p2 = p; 300 } 301 302 void testNonPODMove() { 303 NonPOD p; 304 p.x = 1; 305 NonPOD p2; 306 p2 = move(p); 307 } 308 309 void testNonPODWrapper() { 310 NonPODWrapper w; 311 w.p.y = 1; 312 NonPODWrapper w2; 313 w2 = w; 314 } 315 316 void testNonPODWrapperMove() { 317 NonPODWrapper w; 318 w.p.y = 1; 319 NonPODWrapper w2; 320 w2 = move(w); 321 } 322 } 323} 324 325namespace ArrayMembers { 326 struct Primitive { 327 int values[3]; 328 }; 329 330 void testPrimitive() { 331 Primitive a = { { 1, 2, 3 } }; 332 333 clang_analyzer_eval(a.values[0] == 1); // expected-warning{{TRUE}} 334 clang_analyzer_eval(a.values[1] == 2); // expected-warning{{TRUE}} 335 clang_analyzer_eval(a.values[2] == 3); // expected-warning{{TRUE}} 336 337 Primitive b = a; 338 339 clang_analyzer_eval(b.values[0] == 1); // expected-warning{{TRUE}} 340 clang_analyzer_eval(b.values[1] == 2); // expected-warning{{TRUE}} 341 clang_analyzer_eval(b.values[2] == 3); // expected-warning{{TRUE}} 342 343 Primitive c; 344 c = b; 345 346 clang_analyzer_eval(c.values[0] == 1); // expected-warning{{TRUE}} 347 clang_analyzer_eval(c.values[1] == 2); // expected-warning{{TRUE}} 348 clang_analyzer_eval(c.values[2] == 3); // expected-warning{{TRUE}} 349 } 350 351 struct NestedPrimitive { 352 int values[2][3]; 353 }; 354 355 void testNestedPrimitive() { 356 NestedPrimitive a = { { { 0, 0, 0 }, { 1, 2, 3 } } }; 357 358 clang_analyzer_eval(a.values[1][0] == 1); // expected-warning{{TRUE}} 359 clang_analyzer_eval(a.values[1][1] == 2); // expected-warning{{TRUE}} 360 clang_analyzer_eval(a.values[1][2] == 3); // expected-warning{{TRUE}} 361 362 NestedPrimitive b = a; 363 364 clang_analyzer_eval(b.values[1][0] == 1); // expected-warning{{TRUE}} 365 clang_analyzer_eval(b.values[1][1] == 2); // expected-warning{{TRUE}} 366 clang_analyzer_eval(b.values[1][2] == 3); // expected-warning{{TRUE}} 367 368 NestedPrimitive c; 369 c = b; 370 371 clang_analyzer_eval(c.values[1][0] == 1); // expected-warning{{TRUE}} 372 clang_analyzer_eval(c.values[1][1] == 2); // expected-warning{{TRUE}} 373 clang_analyzer_eval(c.values[1][2] == 3); // expected-warning{{TRUE}} 374 } 375 376 struct POD { 377 IntWrapper values[3]; 378 }; 379 380 void testPOD() { 381 POD a = { { { 1 }, { 2 }, { 3 } } }; 382 383 clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}} 384 clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}} 385 clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}} 386 387 POD b = a; 388 389 clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{TRUE}} 390 clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{TRUE}} 391 clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{TRUE}} 392 393 POD c; 394 c = b; 395 396 clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{TRUE}} 397 clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{TRUE}} 398 clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{TRUE}} 399 } 400 401 struct NestedPOD { 402 IntWrapper values[2][3]; 403 }; 404 405 void testNestedPOD() { 406 NestedPOD a = { { { { 0 }, { 0 }, { 0 } }, { { 1 }, { 2 }, { 3 } } } }; 407 408 clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}} 409 clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}} 410 clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}} 411 412 NestedPOD b = a; 413 414 clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{TRUE}} 415 clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{TRUE}} 416 clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{TRUE}} 417 418 NestedPOD c; 419 c = b; 420 421 clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{TRUE}} 422 clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{TRUE}} 423 clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{TRUE}} 424 } 425 426 struct NonPOD { 427 NonPODIntWrapper values[3]; 428 }; 429 430 void testNonPOD() { 431 NonPOD a; 432 a.values[0].x = 1; 433 a.values[1].x = 2; 434 a.values[2].x = 3; 435 436 clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}} 437 clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}} 438 clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}} 439 440 NonPOD b = a; 441 442 clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}} 443 clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}} 444 clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}} 445 446 NonPOD c; 447 c = b; 448 449 clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}} 450 clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}} 451 clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}} 452 } 453 454 struct NestedNonPOD { 455 NonPODIntWrapper values[2][3]; 456 }; 457 458 void testNestedNonPOD() { 459 NestedNonPOD a; 460 a.values[0][0].x = 0; 461 a.values[0][1].x = 0; 462 a.values[0][2].x = 0; 463 a.values[1][0].x = 1; 464 a.values[1][1].x = 2; 465 a.values[1][2].x = 3; 466 467 clang_analyzer_eval(a.values[1][0].x == 1); // expected-warning{{TRUE}} 468 clang_analyzer_eval(a.values[1][1].x == 2); // expected-warning{{TRUE}} 469 clang_analyzer_eval(a.values[1][2].x == 3); // expected-warning{{TRUE}} 470 471 NestedNonPOD b = a; 472 473 clang_analyzer_eval(b.values[1][0].x == 1); // expected-warning{{UNKNOWN}} 474 clang_analyzer_eval(b.values[1][1].x == 2); // expected-warning{{UNKNOWN}} 475 clang_analyzer_eval(b.values[1][2].x == 3); // expected-warning{{UNKNOWN}} 476 477 NestedNonPOD c; 478 c = b; 479 480 clang_analyzer_eval(c.values[1][0].x == 1); // expected-warning{{UNKNOWN}} 481 clang_analyzer_eval(c.values[1][1].x == 2); // expected-warning{{UNKNOWN}} 482 clang_analyzer_eval(c.values[1][2].x == 3); // expected-warning{{UNKNOWN}} 483 } 484 485 struct NonPODDefaulted { 486 NonPODIntWrapper values[3]; 487 488 NonPODDefaulted() = default; 489 NonPODDefaulted(const NonPODDefaulted &) = default; 490 NonPODDefaulted &operator=(const NonPODDefaulted &) = default; 491 }; 492 493 void testNonPODDefaulted() { 494 NonPODDefaulted a; 495 a.values[0].x = 1; 496 a.values[1].x = 2; 497 a.values[2].x = 3; 498 499 clang_analyzer_eval(a.values[0].x == 1); // expected-warning{{TRUE}} 500 clang_analyzer_eval(a.values[1].x == 2); // expected-warning{{TRUE}} 501 clang_analyzer_eval(a.values[2].x == 3); // expected-warning{{TRUE}} 502 503 NonPODDefaulted b = a; 504 505 clang_analyzer_eval(b.values[0].x == 1); // expected-warning{{UNKNOWN}} 506 clang_analyzer_eval(b.values[1].x == 2); // expected-warning{{UNKNOWN}} 507 clang_analyzer_eval(b.values[2].x == 3); // expected-warning{{UNKNOWN}} 508 509 NonPODDefaulted c; 510 c = b; 511 512 clang_analyzer_eval(c.values[0].x == 1); // expected-warning{{UNKNOWN}} 513 clang_analyzer_eval(c.values[1].x == 2); // expected-warning{{UNKNOWN}} 514 clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}} 515 } 516}; 517 518namespace VirtualInheritance { 519 int counter; 520 521 struct base { 522 base() { 523 ++counter; 524 } 525 }; 526 527 struct virtual_subclass : public virtual base { 528 virtual_subclass() {} 529 }; 530 531 struct double_subclass : public virtual_subclass { 532 double_subclass() {} 533 }; 534 535 void test() { 536 counter = 0; 537 double_subclass obj; 538 clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}} 539 } 540 541 struct double_virtual_subclass : public virtual virtual_subclass { 542 double_virtual_subclass() {} 543 }; 544 545 void testVirtual() { 546 counter = 0; 547 double_virtual_subclass obj; 548 clang_analyzer_eval(counter == 1); // expected-warning{{TRUE}} 549 } 550} 551 552namespace ZeroInitialization { 553 struct raw_pair { 554 int p1; 555 int p2; 556 }; 557 558 void testVarDecl() { 559 raw_pair p{}; 560 clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}} 561 clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}} 562 } 563 564 void testTemporary() { 565 clang_analyzer_eval(raw_pair().p1 == 0); // expected-warning{{TRUE}} 566 clang_analyzer_eval(raw_pair().p2 == 0); // expected-warning{{TRUE}} 567 } 568 569 void testArray() { 570 raw_pair p[2] = {}; 571 clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{TRUE}} 572 clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{TRUE}} 573 clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{TRUE}} 574 clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{TRUE}} 575 } 576 577 void testNew() { 578 raw_pair *pp = new raw_pair(); 579 clang_analyzer_eval(pp->p1 == 0); // expected-warning{{TRUE}} 580 clang_analyzer_eval(pp->p2 == 0); // expected-warning{{TRUE}} 581 } 582 583 void testArrayNew() { 584 // FIXME: Pending proper implementation of constructors for 'new[]'. 585 raw_pair *p = new raw_pair[2](); 586 clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{UNKNOWN}} 587 clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{UNKNOWN}} 588 clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{UNKNOWN}} 589 clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{UNKNOWN}} 590 } 591 592 struct initializing_pair { 593 public: 594 int x; 595 raw_pair y; 596 initializing_pair() : x(), y() {} 597 }; 598 599 void testFieldInitializers() { 600 initializing_pair p; 601 clang_analyzer_eval(p.x == 0); // expected-warning{{TRUE}} 602 clang_analyzer_eval(p.y.p1 == 0); // expected-warning{{TRUE}} 603 clang_analyzer_eval(p.y.p2 == 0); // expected-warning{{TRUE}} 604 } 605 606 struct subclass : public raw_pair { 607 subclass() = default; 608 }; 609 610 void testSubclass() { 611 subclass p; 612 clang_analyzer_eval(p.p1 == 0); // expected-warning{{garbage}} 613 } 614 615 struct initializing_subclass : public raw_pair { 616 initializing_subclass() : raw_pair() {} 617 }; 618 619 void testInitializingSubclass() { 620 initializing_subclass p; 621 clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}} 622 clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}} 623 } 624 625 struct pair_wrapper { 626 pair_wrapper() : p() {} 627 raw_pair p; 628 }; 629 630 struct virtual_subclass : public virtual pair_wrapper { 631 virtual_subclass() {} 632 }; 633 634 struct double_virtual_subclass : public virtual_subclass { 635 double_virtual_subclass() { 636 // This previously caused a crash because the pair_wrapper subobject was 637 // initialized twice. 638 } 639 }; 640 641 class Empty { 642 public: 643 static int glob; 644 Empty(); // No body. 645 Empty(int x); // Body below. 646 }; 647 648 class PairContainer : public Empty { 649 public: 650 raw_pair p; 651 int q; 652 PairContainer() : Empty(), p() { 653 // This previously caused a crash because the empty base class looked 654 // like an initialization of 'p'. 655 } 656 PairContainer(int) : Empty(), p() { 657 // Test inlining something else here. 658 } 659 PairContainer(double): Empty(1), p() { 660 clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}} 661 clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}} 662 663 clang_analyzer_eval(q == 1); // expected-warning{{TRUE}} 664 665 // This one's indeed UNKNOWN. Definitely not TRUE. 666 clang_analyzer_eval(p.p2 == glob); // expected-warning{{UNKNOWN}} 667 } 668 }; 669 670 Empty::Empty(int x) { 671 static_cast<PairContainer *>(this)->p.p1 = x; 672 static_cast<PairContainer *>(this)->q = x; 673 // Our static member will store the old garbage values of fields that aren't 674 // yet initialized. It's not certainly garbage though (i.e. the constructor 675 // could have been called on an initialized piece of memory), so no 676 // uninitialized value warning here, and it should be a symbol, not 677 // undefined value, for later comparison. 678 glob = static_cast<PairContainer *>(this)->p.p2; 679 } 680 681 class Empty2 { 682 public: 683 static int glob_p1, glob_p2; 684 Empty2(); // Body below. 685 }; 686 687 class PairDoubleEmptyContainer: public Empty, public Empty2 { 688 public: 689 raw_pair p; 690 PairDoubleEmptyContainer(): Empty(), Empty2(), p() { 691 clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}} 692 clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}} 693 694 // This is indeed UNKNOWN. 695 clang_analyzer_eval(p.p1 == glob_p1); // expected-warning{{UNKNOWN}} 696 clang_analyzer_eval(p.p2 == glob_p2); // expected-warning{{UNKNOWN}} 697 } 698 }; 699 700 Empty2::Empty2() { 701 glob_p1 = static_cast<PairDoubleEmptyContainer *>(this)->p.p1; 702 glob_p2 = static_cast<PairDoubleEmptyContainer *>(this)->p.p2; 703 } 704 705 class PairContainerContainer { 706 int padding; 707 PairContainer pc; 708 public: 709 PairContainerContainer() : pc(1) {} 710 }; 711} 712 713namespace InitializerList { 714 struct List { 715 bool usedInitializerList; 716 717 List() : usedInitializerList(false) {} 718 List(std::initializer_list<int>) : usedInitializerList(true) {} 719 }; 720 721 void testStatic() { 722 List defaultCtor; 723 clang_analyzer_eval(!defaultCtor.usedInitializerList); // expected-warning{{TRUE}} 724 725 List list{1, 2}; 726 clang_analyzer_eval(list.usedInitializerList); // expected-warning{{TRUE}} 727 } 728 729 void testDynamic() { 730 List *list = new List{1, 2}; 731 clang_analyzer_eval(list->usedInitializerList); // expected-warning{{TRUE}} 732 } 733} 734 735namespace PR19579 { 736 class C {}; 737 738 void f() { 739 C(); 740 int a; 741 742 extern void use(int); 743 use(a); // expected-warning{{uninitialized}} 744 } 745 746 void g() { 747 struct S { 748 C c; 749 int i; 750 }; 751 752 // This order triggers the initialization of the inner "a" after the 753 // constructor for "C" is run, which used to confuse the analyzer 754 // (is "C()" the initialization of "a"?). 755 struct S s = { 756 C(), 757 ({ 758 int a, b = 0; 759 0; 760 }) 761 }; 762 } 763} 764 765namespace NoCrashOnEmptyBaseOptimization { 766 struct NonEmptyBase { 767 int X; 768 explicit NonEmptyBase(int X) : X(X) {} 769 }; 770 771 struct EmptyBase {}; 772 773 struct S : NonEmptyBase, EmptyBase { 774 S() : NonEmptyBase(0), EmptyBase() {} 775 }; 776 777 void testSCtorNoCrash() { 778 S s; 779 } 780} 781 782namespace EmptyBaseAssign { 783struct B1 {}; 784struct B2 { int x; }; 785struct D: public B1, public B2 { 786const D &operator=(const D &d) { 787 *((B2 *)this) = d; 788 *((B1 *)this) = d; 789 return *this; 790} 791}; 792 793void test() { 794 D d1; 795 d1.x = 1; 796 D d2; 797 d2 = d1; 798 clang_analyzer_eval(d2.x == 1); // expected-warning{{TRUE}} 799} 800} 801 802namespace vbase_zero_init { 803class A { 804 virtual void foo(); 805}; 806 807class B { 808 virtual void bar(); 809public: 810 static int glob_y, glob_z, glob_w; 811 int x; 812 B(); // Body below. 813}; 814 815class C : virtual public A { 816public: 817 int y; 818}; 819 820class D : public B, public C { 821public: 822 // 'z', unlike 'w', resides in an area that would have been within padding of 823 // base class 'C' if it wasn't part of 'D', but only on 64-bit systems. 824 int z, w; 825 // Initialization order: A(), B(), C(). 826 D() : A(), C() { 827 clang_analyzer_eval(x == 1); // expected-warning{{TRUE}} 828 clang_analyzer_eval(y == 0); // expected-warning{{TRUE}} 829#ifdef I386 830 clang_analyzer_eval(z == 3); // expected-warning{{TRUE}} 831#else 832 // FIXME: Should be TRUE. Initialized in B(). 833 clang_analyzer_eval(z == 3); // expected-warning{{UNKNOWN}} 834#endif 835 clang_analyzer_eval(w == 4); // expected-warning{{TRUE}} 836 837 // FIXME: Should be UNKNOWN. Changed in B() since glob_y was assigned. 838 clang_analyzer_eval(y == glob_y); // expected-warning{{TRUE}} 839 840#ifdef I386 841 clang_analyzer_eval(z == glob_z); // expected-warning{{UNKNOWN}} 842#else 843 // FIXME: Should be UNKNOWN. Changed in B() since glob_z was assigned. 844 clang_analyzer_eval(z == glob_z); // expected-warning{{TRUE}} 845#endif 846 847 clang_analyzer_eval(w == glob_w); // expected-warning{{UNKNOWN}} 848 } // no-crash 849}; 850 851B::B() : x(1) { 852 // Our static members will store the old garbage values of fields that aren't 853 // yet initialized. These aren't certainly garbage though (i.e. the 854 // constructor could have been called on an initialized piece of memory), 855 // so no uninitialized value warning here, and these should be symbols, not 856 // undefined values, for later comparison. 857 glob_y = static_cast<D *>(this)->y; 858 glob_z = static_cast<D *>(this)->z; 859 glob_w = static_cast<D *>(this)->w; 860 static_cast<D *>(this)->y = 2; 861 static_cast<D *>(this)->z = 3; 862 static_cast<D *>(this)->w = 4; 863} 864} 865