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