summaryrefslogtreecommitdiff
path: root/test/Analysis/cxx-uninitialized-object-inheritance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/cxx-uninitialized-object-inheritance.cpp')
-rw-r--r--test/Analysis/cxx-uninitialized-object-inheritance.cpp775
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();
+}