// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \ // RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ // RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ // RUN: -std=c++11 -verify %s //===----------------------------------------------------------------------===// // Non-polymorphic inheritance tests //===----------------------------------------------------------------------===// class NonPolymorphicLeft1 { int x; protected: int y; public: NonPolymorphicLeft1() = default; NonPolymorphicLeft1(int) : x(1) {} }; class NonPolymorphicInheritanceTest1 : public NonPolymorphicLeft1 { int z; public: NonPolymorphicInheritanceTest1() : NonPolymorphicLeft1(int{}) { y = 2; z = 3; // All good! } }; void fNonPolymorphicInheritanceTest1() { NonPolymorphicInheritanceTest1(); } class NonPolymorphicBaseClass2 { int x; // expected-note{{uninitialized field 'this->NonPolymorphicBaseClass2::x'}} protected: int y; public: NonPolymorphicBaseClass2() = default; NonPolymorphicBaseClass2(int) : x(4) {} }; class NonPolymorphicInheritanceTest2 : public NonPolymorphicBaseClass2 { int z; public: NonPolymorphicInheritanceTest2() { y = 5; z = 6; // expected-warning{{1 uninitialized field}} } }; void fNonPolymorphicInheritanceTest2() { NonPolymorphicInheritanceTest2(); } class NonPolymorphicBaseClass3 { int x; protected: int y; // expected-note{{uninitialized field 'this->NonPolymorphicBaseClass3::y'}} public: NonPolymorphicBaseClass3() = default; NonPolymorphicBaseClass3(int) : x(7) {} }; class NonPolymorphicInheritanceTest3 : public NonPolymorphicBaseClass3 { int z; public: NonPolymorphicInheritanceTest3() : NonPolymorphicBaseClass3(int{}) { z = 8; // expected-warning{{1 uninitialized field}} } }; void fNonPolymorphicInheritanceTest3() { NonPolymorphicInheritanceTest3(); } class NonPolymorphicBaseClass4 { int x; protected: int y; public: NonPolymorphicBaseClass4() = default; NonPolymorphicBaseClass4(int) : x(9) {} }; class NonPolymorphicInheritanceTest4 : public NonPolymorphicBaseClass4 { int z; // expected-note{{uninitialized field 'this->z'}} public: NonPolymorphicInheritanceTest4() : NonPolymorphicBaseClass4(int{}) { y = 10; // expected-warning{{1 uninitialized field}} } }; void fNonPolymorphicInheritanceTest4() { NonPolymorphicInheritanceTest4(); } //===----------------------------------------------------------------------===// // Polymorphic inheritance tests //===----------------------------------------------------------------------===// class PolymorphicLeft1 { int x; protected: int y; public: virtual ~PolymorphicLeft1() = default; PolymorphicLeft1() = default; PolymorphicLeft1(int) : x(11) {} }; class PolymorphicInheritanceTest1 : public PolymorphicLeft1 { int z; public: PolymorphicInheritanceTest1() : PolymorphicLeft1(int{}) { y = 12; z = 13; // All good! } }; void fPolymorphicInheritanceTest1() { PolymorphicInheritanceTest1(); } class PolymorphicRight1 { int x; // expected-note{{uninitialized field 'this->PolymorphicRight1::x'}} protected: int y; public: virtual ~PolymorphicRight1() = default; PolymorphicRight1() = default; PolymorphicRight1(int) : x(14) {} }; class PolymorphicInheritanceTest2 : public PolymorphicRight1 { int z; public: PolymorphicInheritanceTest2() { y = 15; z = 16; // expected-warning{{1 uninitialized field}} } }; void fPolymorphicInheritanceTest2() { PolymorphicInheritanceTest2(); } class PolymorphicBaseClass3 { int x; protected: int y; // expected-note{{uninitialized field 'this->PolymorphicBaseClass3::y'}} public: virtual ~PolymorphicBaseClass3() = default; PolymorphicBaseClass3() = default; PolymorphicBaseClass3(int) : x(17) {} }; class PolymorphicInheritanceTest3 : public PolymorphicBaseClass3 { int z; public: PolymorphicInheritanceTest3() : PolymorphicBaseClass3(int{}) { z = 18; // expected-warning{{1 uninitialized field}} } }; void fPolymorphicInheritanceTest3() { PolymorphicInheritanceTest3(); } class PolymorphicBaseClass4 { int x; protected: int y; public: virtual ~PolymorphicBaseClass4() = default; PolymorphicBaseClass4() = default; PolymorphicBaseClass4(int) : x(19) {} }; class PolymorphicInheritanceTest4 : public PolymorphicBaseClass4 { int z; // expected-note{{uninitialized field 'this->z'}} public: PolymorphicInheritanceTest4() : PolymorphicBaseClass4(int{}) { y = 20; // expected-warning{{1 uninitialized field}} } }; void fPolymorphicInheritanceTest4() { PolymorphicInheritanceTest4(); } //===----------------------------------------------------------------------===// // Virtual inheritance tests //===----------------------------------------------------------------------===// class VirtualPolymorphicLeft1 { int x; protected: int y; public: virtual ~VirtualPolymorphicLeft1() = default; VirtualPolymorphicLeft1() = default; VirtualPolymorphicLeft1(int) : x(21) {} }; class VirtualInheritanceTest1 : virtual public VirtualPolymorphicLeft1 { int z; public: VirtualInheritanceTest1() : VirtualPolymorphicLeft1(int()) { y = 22; z = 23; // All good! } }; void fVirtualInheritanceTest1() { VirtualInheritanceTest1(); } class VirtualPolymorphicRight1 { int x; // expected-note{{uninitialized field 'this->VirtualPolymorphicRight1::x'}} protected: int y; public: virtual ~VirtualPolymorphicRight1() = default; VirtualPolymorphicRight1() = default; VirtualPolymorphicRight1(int) : x(24) {} }; class VirtualInheritanceTest2 : virtual public VirtualPolymorphicRight1 { int z; public: VirtualInheritanceTest2() { y = 25; z = 26; // expected-warning{{1 uninitialized field}} } }; void fVirtualInheritanceTest2() { VirtualInheritanceTest2(); } class VirtualPolymorphicBaseClass3 { int x; protected: int y; // expected-note{{uninitialized field 'this->VirtualPolymorphicBaseClass3::y'}} public: virtual ~VirtualPolymorphicBaseClass3() = default; VirtualPolymorphicBaseClass3() = default; VirtualPolymorphicBaseClass3(int) : x(27) {} }; class VirtualInheritanceTest3 : virtual public VirtualPolymorphicBaseClass3 { int z; public: VirtualInheritanceTest3() : VirtualPolymorphicBaseClass3(int{}) { z = 28; // expected-warning{{1 uninitialized field}} } }; void fVirtualInheritanceTest3() { VirtualInheritanceTest3(); } //===----------------------------------------------------------------------===// // Multiple inheritance tests //===----------------------------------------------------------------------===// /* Left Right \ / \ / \ / MultipleInheritanceTest */ struct Left1 { int x; Left1() = default; Left1(int) : x(29) {} }; struct Right1 { int y; Right1() = default; Right1(int) : y(30) {} }; class MultipleInheritanceTest1 : public Left1, public Right1 { int z; public: MultipleInheritanceTest1() : Left1(int{}), Right1(char{}) { z = 31; // All good! } MultipleInheritanceTest1(int) : Left1(int{}) { y = 32; z = 33; // All good! } MultipleInheritanceTest1(int, int) : Right1(char{}) { x = 34; z = 35; // All good! } }; void fMultipleInheritanceTest1() { MultipleInheritanceTest1(); MultipleInheritanceTest1(int()); MultipleInheritanceTest1(int(), int()); } struct Left2 { int x; Left2() = default; Left2(int) : x(36) {} }; struct Right2 { int y; // expected-note{{uninitialized field 'this->Right2::y'}} Right2() = default; Right2(int) : y(37) {} }; class MultipleInheritanceTest2 : public Left2, public Right2 { int z; public: MultipleInheritanceTest2() : Left2(int{}) { z = 38; // expected-warning{{1 uninitialized field}} } }; void fMultipleInheritanceTest2() { MultipleInheritanceTest2(); } struct Left3 { int x; // expected-note{{uninitialized field 'this->Left3::x'}} Left3() = default; Left3(int) : x(39) {} }; struct Right3 { int y; Right3() = default; Right3(int) : y(40) {} }; class MultipleInheritanceTest3 : public Left3, public Right3 { int z; public: MultipleInheritanceTest3() : Right3(char{}) { z = 41; // expected-warning{{1 uninitialized field}} } }; void fMultipleInheritanceTest3() { MultipleInheritanceTest3(); } struct Left4 { int x; Left4() = default; Left4(int) : x(42) {} }; struct Right4 { int y; Right4() = default; Right4(int) : y(43) {} }; class MultipleInheritanceTest4 : public Left4, public Right4 { int z; // expected-note{{uninitialized field 'this->z'}} public: MultipleInheritanceTest4() : Left4(int{}), Right4(char{}) { // expected-warning{{1 uninitialized field}} } }; void fMultipleInheritanceTest4() { MultipleInheritanceTest4(); } struct Left5 { int x; Left5() = default; Left5(int) : x(44) {} }; struct Right5 { int y; // expected-note{{uninitialized field 'this->Right5::y'}} Right5() = default; Right5(int) : y(45) {} }; class MultipleInheritanceTest5 : public Left5, public Right5 { int z; // expected-note{{uninitialized field 'this->z'}} public: MultipleInheritanceTest5() // expected-warning{{2 uninitialized fields}} : Left5(int{}) { } }; void fMultipleInheritanceTest5() { MultipleInheritanceTest5(); } //===----------------------------------------------------------------------===// // Non-virtual diamond inheritance tests //===----------------------------------------------------------------------===// /* NonVirtualBase NonVirtualBase | | | | | | First Second \ / \ / \ / NonVirtualDiamondInheritanceTest */ struct NonVirtualBase1 { int x; NonVirtualBase1() = default; NonVirtualBase1(int) : x(46) {} }; struct First1 : public NonVirtualBase1 { First1() = default; First1(int) : NonVirtualBase1(int{}) {} }; struct Second1 : public NonVirtualBase1 { Second1() = default; Second1(int) : NonVirtualBase1(int{}) {} }; class NonVirtualDiamondInheritanceTest1 : public First1, public Second1 { int z; public: NonVirtualDiamondInheritanceTest1() : First1(int{}), Second1(int{}) { z = 47; // All good! } NonVirtualDiamondInheritanceTest1(int) : First1(int{}) { Second1::x = 48; z = 49; // All good! } NonVirtualDiamondInheritanceTest1(int, int) : Second1(int{}) { First1::x = 50; z = 51; // All good! } }; void fNonVirtualDiamondInheritanceTest1() { NonVirtualDiamondInheritanceTest1(); NonVirtualDiamondInheritanceTest1(int()); NonVirtualDiamondInheritanceTest1(int(), int()); } struct NonVirtualBase2 { int x; // expected-note{{uninitialized field 'this->NonVirtualBase2::x'}} NonVirtualBase2() = default; NonVirtualBase2(int) : x(52) {} }; struct First2 : public NonVirtualBase2 { First2() = default; First2(int) : NonVirtualBase2(int{}) {} }; struct Second2 : public NonVirtualBase2 { Second2() = default; Second2(int) : NonVirtualBase2(int{}) {} }; class NonVirtualDiamondInheritanceTest2 : public First2, public Second2 { int z; public: NonVirtualDiamondInheritanceTest2() : First2(int{}) { z = 53; // expected-warning{{1 uninitialized field}} } }; void fNonVirtualDiamondInheritanceTest2() { NonVirtualDiamondInheritanceTest2(); } struct NonVirtualBase3 { int x; // expected-note{{uninitialized field 'this->NonVirtualBase3::x'}} NonVirtualBase3() = default; NonVirtualBase3(int) : x(54) {} }; struct First3 : public NonVirtualBase3 { First3() = default; First3(int) : NonVirtualBase3(int{}) {} }; struct Second3 : public NonVirtualBase3 { Second3() = default; Second3(int) : NonVirtualBase3(int{}) {} }; class NonVirtualDiamondInheritanceTest3 : public First3, public Second3 { int z; public: NonVirtualDiamondInheritanceTest3() : Second3(int{}) { z = 55; // expected-warning{{1 uninitialized field}} } }; void fNonVirtualDiamondInheritanceTest3() { NonVirtualDiamondInheritanceTest3(); } struct NonVirtualBase4 { int x; // expected-note{{uninitialized field 'this->NonVirtualBase4::x'}} // expected-note@-1{{uninitialized field 'this->NonVirtualBase4::x'}} NonVirtualBase4() = default; NonVirtualBase4(int) : x(56) {} }; struct First4 : public NonVirtualBase4 { First4() = default; First4(int) : NonVirtualBase4(int{}) {} }; struct Second4 : public NonVirtualBase4 { Second4() = default; Second4(int) : NonVirtualBase4(int{}) {} }; class NonVirtualDiamondInheritanceTest4 : public First4, public Second4 { int z; public: NonVirtualDiamondInheritanceTest4() { z = 57; // expected-warning{{2 uninitialized fields}} } }; void fNonVirtualDiamondInheritanceTest4() { NonVirtualDiamondInheritanceTest4(); } struct NonVirtualBase5 { int x; NonVirtualBase5() = default; NonVirtualBase5(int) : x(58) {} }; struct First5 : public NonVirtualBase5 { First5() = default; First5(int) : NonVirtualBase5(int{}) {} }; struct Second5 : public NonVirtualBase5 { Second5() = default; Second5(int) : NonVirtualBase5(int{}) {} }; class NonVirtualDiamondInheritanceTest5 : public First5, public Second5 { int z; // expected-note{{uninitialized field 'this->z'}} public: NonVirtualDiamondInheritanceTest5() : First5(int{}), Second5(int{}) { // expected-warning{{1 uninitialized field}} } }; void fNonVirtualDiamondInheritanceTest5() { NonVirtualDiamondInheritanceTest5(); } struct NonVirtualBase6 { int x; // expected-note{{uninitialized field 'this->NonVirtualBase6::x'}} NonVirtualBase6() = default; NonVirtualBase6(int) : x(59) {} }; struct First6 : public NonVirtualBase6 { First6() = default; First6(int) : NonVirtualBase6(int{}) {} }; struct Second6 : public NonVirtualBase6 { Second6() = default; Second6(int) : NonVirtualBase6(int{}) {} }; class NonVirtualDiamondInheritanceTest6 : public First6, public Second6 { int z; // expected-note{{uninitialized field 'this->z'}} public: NonVirtualDiamondInheritanceTest6() // expected-warning{{2 uninitialized fields}} : First6(int{}) { // 'z' and 'Second::x' unintialized } }; void fNonVirtualDiamondInheritanceTest6() { NonVirtualDiamondInheritanceTest6(); } //===----------------------------------------------------------------------===// // Virtual diamond inheritance tests //===----------------------------------------------------------------------===// /* VirtualBase / \ / \ / \ VirtualFirst VirtualSecond \ / \ / \ / VirtualDiamondInheritanceTest */ struct VirtualBase1 { int x; VirtualBase1() = default; VirtualBase1(int) : x(60) {} }; struct VirtualFirst1 : virtual public VirtualBase1 { VirtualFirst1() = default; VirtualFirst1(int) : VirtualBase1(int{}) {} VirtualFirst1(int, int) { x = 61; } }; struct VirtualSecond1 : virtual public VirtualBase1 { VirtualSecond1() = default; VirtualSecond1(int) : VirtualBase1(int{}) {} VirtualSecond1(int, int) { x = 62; } }; class VirtualDiamondInheritanceTest1 : public VirtualFirst1, public VirtualSecond1 { public: VirtualDiamondInheritanceTest1() { x = 0; // All good! } VirtualDiamondInheritanceTest1(int) : VirtualFirst1(int{}, int{}), VirtualSecond1(int{}, int{}) { // All good! } VirtualDiamondInheritanceTest1(int, int) : VirtualFirst1(int{}, int{}) { // All good! } }; void fVirtualDiamondInheritanceTest1() { VirtualDiamondInheritanceTest1(); VirtualDiamondInheritanceTest1(int()); VirtualDiamondInheritanceTest1(int(), int()); } struct VirtualBase2 { int x; // expected-note{{uninitialized field 'this->VirtualBase2::x'}} VirtualBase2() = default; VirtualBase2(int) : x(63) {} }; struct VirtualFirst2 : virtual public VirtualBase2 { VirtualFirst2() = default; VirtualFirst2(int) : VirtualBase2(int{}) {} VirtualFirst2(int, int) { x = 64; } }; struct VirtualSecond2 : virtual public VirtualBase2 { VirtualSecond2() = default; VirtualSecond2(int) : VirtualBase2(int{}) {} VirtualSecond2(int, int) { x = 65; } }; class VirtualDiamondInheritanceTest2 : public VirtualFirst2, public VirtualSecond2 { public: VirtualDiamondInheritanceTest2() // expected-warning{{1 uninitialized field}} : VirtualFirst2(int{}) { // From the N4659 C++ Standard Working Draft: // // (15.6.2.7) // [...] A 'mem-initializer' where the 'mem-initializer-id' denotes a // virtual base class is ignored during execution of a constructor of any // class that is not the most derived class. // // This means that Left1::x will not be initialized, because in both // VirtualFirst::VirtualFirst(int) and VirtualSecond::VirtualSecond(int) // the constructor delegation to Left1::Left1(int) will be // ignored. } }; void fVirtualDiamondInheritanceTest2() { VirtualDiamondInheritanceTest2(); } struct VirtualBase3 { int x; // expected-note{{uninitialized field 'this->VirtualBase3::x'}} VirtualBase3() = default; VirtualBase3(int) : x(66) {} }; struct VirtualFirst3 : virtual public VirtualBase3 { VirtualFirst3() = default; VirtualFirst3(int) : VirtualBase3(int{}) {} VirtualFirst3(int, int) { x = 67; } }; struct VirtualSecond3 : virtual public VirtualBase3 { VirtualSecond3() = default; VirtualSecond3(int) : VirtualBase3(int{}) {} VirtualSecond3(int, int) { x = 68; } }; class VirtualDiamondInheritanceTest3 : public VirtualFirst3, public VirtualSecond3 { public: VirtualDiamondInheritanceTest3() // expected-warning{{1 uninitialized field}} : VirtualFirst3(int{}) {} }; void fVirtualDiamondInheritanceTest3() { VirtualDiamondInheritanceTest3(); } //===----------------------------------------------------------------------===// // Dynamic type test. //===----------------------------------------------------------------------===// struct DynTBase1 {}; struct DynTDerived1 : DynTBase1 { int y; // expected-note{{uninitialized field 'static_cast(this->bptr)->y'}} }; struct DynamicTypeTest1 { DynTBase1 *bptr; int i = 0; DynamicTypeTest1(DynTBase1 *bptr) : bptr(bptr) {} // expected-warning{{1 uninitialized field}} }; void fDynamicTypeTest1() { DynTDerived1 d; DynamicTypeTest1 t(&d); }; struct DynTBase2 { int x; // expected-note{{uninitialized field 'static_cast(this->bptr)->DynTBase2::x'}} }; struct DynTDerived2 : DynTBase2 { int y; // expected-note{{uninitialized field 'static_cast(this->bptr)->y'}} }; struct DynamicTypeTest2 { DynTBase2 *bptr; int i = 0; DynamicTypeTest2(DynTBase2 *bptr) : bptr(bptr) {} // expected-warning{{2 uninitialized fields}} }; void fDynamicTypeTest2() { DynTDerived2 d; DynamicTypeTest2 t(&d); } struct SymbolicSuperRegionBase { SymbolicSuperRegionBase() {} }; struct SymbolicSuperRegionDerived : SymbolicSuperRegionBase { SymbolicSuperRegionBase *bptr; // no-crash SymbolicSuperRegionDerived(SymbolicSuperRegionBase *bptr) : bptr(bptr) {} }; SymbolicSuperRegionDerived *getSymbolicRegion(); void fSymbolicSuperRegionTest() { SymbolicSuperRegionDerived test(getSymbolicRegion()); }