diff options
Diffstat (limited to 'test/Analysis/cxx-uninitialized-object-inheritance.cpp')
-rw-r--r-- | test/Analysis/cxx-uninitialized-object-inheritance.cpp | 775 |
1 files changed, 775 insertions, 0 deletions
diff --git a/test/Analysis/cxx-uninitialized-object-inheritance.cpp b/test/Analysis/cxx-uninitialized-object-inheritance.cpp new file mode 100644 index 0000000000000..3b048b759e13b --- /dev/null +++ b/test/Analysis/cxx-uninitialized-object-inheritance.cpp @@ -0,0 +1,775 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -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->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->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->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->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->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->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->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->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->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->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->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->x'}} + // expected-note@-1{{uninitialized field 'this->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->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->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->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(); +} |