diff options
author | Kristof Umann <dkszelethus@gmail.com> | 2018-06-18 11:50:17 +0000 |
---|---|---|
committer | Kristof Umann <dkszelethus@gmail.com> | 2018-06-18 11:50:17 +0000 |
commit | 6402a97d5b74108b300f5833af0b85b3d4c5d6b6 (patch) | |
tree | d8cbd3c62fb05b37fada65472a1f9b6d48507eb4 /test/Analysis/cxx-uninitialized-object.cpp | |
parent | 07caa7f2a1dae8d2569ec59a2f6785ad5d4ea3d9 (diff) |
[analyzer] Checker for uninitialized C++ objects
This checker analyzes C++ constructor calls, and reports uninitialized fields.
Due to the nature of this problem (uninitialized fields after an object
construction), this checker doesn't search for bugs, but rather is a tool to
enforce a specific programming model where every field needs to be initialized.
This checker lands in alpha for now, and a number of followup patches will be
made to reduce false negatives and to make it easier for the user to understand
what rules the checker relies on, eg. whether a derived class' constructor is
responsible for initializing inherited data members or whether it should be
handled in the base class' constructor.
Differential Revision: https://reviews.llvm.org/D45532
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334935 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/cxx-uninitialized-object.cpp')
-rw-r--r-- | test/Analysis/cxx-uninitialized-object.cpp | 1058 |
1 files changed, 1058 insertions, 0 deletions
diff --git a/test/Analysis/cxx-uninitialized-object.cpp b/test/Analysis/cxx-uninitialized-object.cpp new file mode 100644 index 0000000000..617ac78f40 --- /dev/null +++ b/test/Analysis/cxx-uninitialized-object.cpp @@ -0,0 +1,1058 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -std=c++11 -DPEDANTIC -verify %s + +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -std=c++11 -verify %s + +//===----------------------------------------------------------------------===// +// Default constructor test. +//===----------------------------------------------------------------------===// + +class CompilerGeneratedConstructorTest { + int a, b, c, d, e, f, g, h, i, j; + +public: + CompilerGeneratedConstructorTest() = default; +}; + +void fCompilerGeneratedConstructorTest() { + CompilerGeneratedConstructorTest(); +} + +#ifdef PEDANTIC +class DefaultConstructorTest { + int a; // expected-note{{uninitialized field 'this->a'}} + +public: + DefaultConstructorTest(); +}; + +DefaultConstructorTest::DefaultConstructorTest() = default; + +void fDefaultConstructorTest() { + DefaultConstructorTest(); // expected-warning{{1 uninitialized field}} +} +#else +class DefaultConstructorTest { + int a; + +public: + DefaultConstructorTest(); +}; + +DefaultConstructorTest::DefaultConstructorTest() = default; + +void fDefaultConstructorTest() { + DefaultConstructorTest(); +} +#endif // PEDANTIC + +//===----------------------------------------------------------------------===// +// Initializer list test. +//===----------------------------------------------------------------------===// + +class InitListTest1 { + int a; + int b; + +public: + InitListTest1() + : a(1), + b(2) { + // All good! + } +}; + +void fInitListTest1() { + InitListTest1(); +} + +class InitListTest2 { + int a; + int b; // expected-note{{uninitialized field 'this->b'}} + +public: + InitListTest2() + : a(3) {} // expected-warning{{1 uninitialized field}} +}; + +void fInitListTest2() { + InitListTest2(); +} + +class InitListTest3 { + int a; // expected-note{{uninitialized field 'this->a'}} + int b; + +public: + InitListTest3() + : b(4) {} // expected-warning{{1 uninitialized field}} +}; + +void fInitListTest3() { + InitListTest3(); +} + +//===----------------------------------------------------------------------===// +// Constructor body test. +//===----------------------------------------------------------------------===// + +class CtorBodyTest1 { + int a, b; + +public: + CtorBodyTest1() { + a = 5; + b = 6; + // All good! + } +}; + +void fCtorBodyTest1() { + CtorBodyTest1(); +} + +class CtorBodyTest2 { + int a; + int b; // expected-note{{uninitialized field 'this->b'}} + +public: + CtorBodyTest2() { + a = 7; // expected-warning{{1 uninitialized field}} + } +}; + +void fCtorBodyTest2() { + CtorBodyTest2(); +} + +class CtorBodyTest3 { + int a; // expected-note{{uninitialized field 'this->a'}} + int b; + +public: + CtorBodyTest3() { + b = 8; // expected-warning{{1 uninitialized field}} + } +}; + +void fCtorBodyTest3() { + CtorBodyTest3(); +} + +#ifdef PEDANTIC +class CtorBodyTest4 { + int a; // expected-note{{uninitialized field 'this->a'}} + int b; // expected-note{{uninitialized field 'this->b'}} + +public: + CtorBodyTest4() {} +}; + +void fCtorBodyTest4() { + CtorBodyTest4(); // expected-warning{{2 uninitialized fields}} +} +#else +class CtorBodyTest4 { + int a; + int b; + +public: + CtorBodyTest4() {} +}; + +void fCtorBodyTest4() { + CtorBodyTest4(); +} +#endif + +//===----------------------------------------------------------------------===// +// Constructor delegation test. +//===----------------------------------------------------------------------===// + +class CtorDelegationTest1 { + int a; + int b; + +public: + CtorDelegationTest1(int) + : a(9) { + // leaves 'b' unintialized, but we'll never check this function + } + + CtorDelegationTest1() + : CtorDelegationTest1(int{}) { // Initializing 'a' + b = 10; + // All good! + } +}; + +void fCtorDelegationTest1() { + CtorDelegationTest1(); +} + +class CtorDelegationTest2 { + int a; // expected-note{{uninitialized field 'this->a'}} + int b; + +public: + CtorDelegationTest2(int) + : b(11) { + // leaves 'a' unintialized, but we'll never check this function + } + + CtorDelegationTest2() + : CtorDelegationTest2(int{}) { // expected-warning{{1 uninitialized field}} + } +}; + +void fCtorDelegationTest2() { + CtorDelegationTest2(); +} + +//===----------------------------------------------------------------------===// +// Tests for classes containing records. +//===----------------------------------------------------------------------===// + +class ContainsRecordTest1 { + struct RecordType { + int x; + int y; + } rec; + int c, d; + +public: + ContainsRecordTest1() + : rec({12, 13}), + c(14), + d(15) { + // All good! + } +}; + +void fContainsRecordTest1() { + ContainsRecordTest1(); +} + +class ContainsRecordTest2 { + struct RecordType { + int x; + int y; // expected-note{{uninitialized field 'this->rec.y'}} + } rec; + int c, d; + +public: + ContainsRecordTest2() + : c(16), + d(17) { + rec.x = 18; // expected-warning{{1 uninitialized field}} + } +}; + +void fContainsRecordTest2() { + ContainsRecordTest2(); +} + +class ContainsRecordTest3 { + struct RecordType { + int x; // expected-note{{uninitialized field 'this->rec.x'}} + int y; // expected-note{{uninitialized field 'this->rec.y'}} + } rec; + int c, d; + +public: + ContainsRecordTest3() + : c(19), + d(20) { // expected-warning{{2 uninitialized fields}} + } +}; + +void fContainsRecordTest3() { + ContainsRecordTest3(); +} + +class ContainsRecordTest4 { + struct RecordType { + int x; // expected-note{{uninitialized field 'this->rec.x'}} + int y; // expected-note{{uninitialized field 'this->rec.y'}} + } rec; + int c, d; // expected-note{{uninitialized field 'this->d'}} + +public: + ContainsRecordTest4() + : c(19) { // expected-warning{{3 uninitialized fields}} + } +}; + +void fContainsRecordTest4() { + ContainsRecordTest4(); +} + +//===----------------------------------------------------------------------===// +// Tests for template classes. +//===----------------------------------------------------------------------===// + +template <class T> +class IntTemplateClassTest1 { + T t; + int b; + +public: + IntTemplateClassTest1(T i) { + b = 21; + t = i; + // All good! + } +}; + +void fIntTemplateClassTest1() { + IntTemplateClassTest1<int>(22); +} + +template <class T> +class IntTemplateClassTest2 { + T t; // expected-note{{uninitialized field 'this->t'}} + int b; + +public: + IntTemplateClassTest2() { + b = 23; // expected-warning{{1 uninitialized field}} + } +}; + +void fIntTemplateClassTest2() { + IntTemplateClassTest2<int>(); +} + +struct Record { + int x; // expected-note{{uninitialized field 'this->t.x'}} + int y; // expected-note{{uninitialized field 'this->t.y'}} +}; + +template <class T> +class RecordTemplateClassTest { + T t; + int b; + +public: + RecordTemplateClassTest() { + b = 24; // expected-warning{{2 uninitialized fields}} + } +}; + +void fRecordTemplateClassTest() { + RecordTemplateClassTest<Record>(); +} + +//===----------------------------------------------------------------------===// +// Tests involving functions with unknown implementations. +//===----------------------------------------------------------------------===// + +template <class T> +void mayInitialize(T &); + +template <class T> +void wontInitialize(const T &); + +class PassingToUnknownFunctionTest1 { + int a, b; + +public: + PassingToUnknownFunctionTest1() { + mayInitialize(a); + mayInitialize(b); + // All good! + } + + PassingToUnknownFunctionTest1(int) { + mayInitialize(a); + // All good! + } + + PassingToUnknownFunctionTest1(int, int) { + mayInitialize(*this); + // All good! + } +}; + +void fPassingToUnknownFunctionTest1() { + PassingToUnknownFunctionTest1(); + PassingToUnknownFunctionTest1(int()); + PassingToUnknownFunctionTest1(int(), int()); +} + +class PassingToUnknownFunctionTest2 { + int a; // expected-note{{uninitialized field 'this->a'}} + int b; + +public: + PassingToUnknownFunctionTest2() { + wontInitialize(a); + b = 4; // expected-warning{{1 uninitialized field}} + } +}; + +void fPassingToUnknownFunctionTest2() { + PassingToUnknownFunctionTest2(); +} + +//===----------------------------------------------------------------------===// +// Tests for classes containing unions. +//===----------------------------------------------------------------------===// + +// FIXME: As of writing this checker, there is no good support for union types +// in the Static Analyzer. Here is non-exhaustive list of cases. +// Note that the rules for unions are different in C and C++. +// http://lists.llvm.org/pipermail/cfe-dev/2017-March/052910.html + +class ContainsSimpleUnionTest1 { + union SimpleUnion { + float uf; + int ui; + char uc; + } u; + +public: + ContainsSimpleUnionTest1() { + u.uf = 3.14; + // All good! + } +}; + +void fContainsSimpleUnionTest1() { + ContainsSimpleUnionTest1(); +} + +class ContainsSimpleUnionTest2 { + union SimpleUnion { + float uf; + int ui; + char uc; + // TODO: we'd expect the note: {{uninitialized field 'this->u'}} + } u; // no-note + +public: + ContainsSimpleUnionTest2() {} +}; + +void fContainsSimpleUnionTest2() { + // TODO: we'd expect the warning: {{1 uninitialized field}} + ContainsSimpleUnionTest2(); // no-warning +} + +class UnionPointerTest1 { +public: + union SimpleUnion { + float uf; + int ui; + char uc; + }; + +private: + SimpleUnion *uptr; + +public: + UnionPointerTest1(SimpleUnion *uptr, int) : uptr(uptr) { + // All good! + } +}; + +void fUnionPointerTest1() { + UnionPointerTest1::SimpleUnion u; + u.uf = 41; + UnionPointerTest1(&u, int()); +} + +class UnionPointerTest2 { +public: + union SimpleUnion { + float uf; + int ui; + char uc; + }; + +private: + // TODO: we'd expect the note: {{uninitialized field 'this->uptr'}} + SimpleUnion *uptr; // no-note + +public: + UnionPointerTest2(SimpleUnion *uptr, char) : uptr(uptr) {} +}; + +void fUnionPointerTest2() { + UnionPointerTest2::SimpleUnion u; + // TODO: we'd expect the warning: {{1 uninitialized field}} + UnionPointerTest2(&u, int()); // no-warning +} + +class ContainsUnionWithRecordTest1 { + union UnionWithRecord { + struct RecordType { + int x; + int y; + } us; + double ud; + long ul; + + UnionWithRecord(){}; + } u; + +public: + ContainsUnionWithRecordTest1() { + u.ud = 3.14; + // All good! + } +}; + +void fContainsUnionWithRecordTest1() { + ContainsUnionWithRecordTest1(); +} + +class ContainsUnionWithRecordTest2 { + union UnionWithRecord { + struct RecordType { + int x; + int y; + } us; + double ud; + long ul; + + UnionWithRecord(){}; + } u; + +public: + ContainsUnionWithRecordTest2() { + u.us = UnionWithRecord::RecordType{42, 43}; + // All good! + } +}; + +void fContainsUnionWithRecordTest2() { + ContainsUnionWithRecordTest1(); +} + +class ContainsUnionWithRecordTest3 { + union UnionWithRecord { + struct RecordType { + int x; + int y; + } us; + double ud; + long ul; + + UnionWithRecord(){}; + // TODO: we'd expect the note: {{uninitialized field 'this->u'}} + } u; // no-note + +public: + ContainsUnionWithRecordTest3() { + UnionWithRecord::RecordType rec; + rec.x = 44; + // TODO: we'd expect the warning: {{1 uninitialized field}} + u.us = rec; // no-warning + } +}; + +void fContainsUnionWithRecordTest3() { + ContainsUnionWithRecordTest3(); +} + +class ContainsUnionWithSimpleUnionTest1 { + union UnionWithSimpleUnion { + union SimpleUnion { + float uf; + int ui; + char uc; + } usu; + long ul; + unsigned uu; + } u; + +public: + ContainsUnionWithSimpleUnionTest1() { + u.usu.ui = 5; + // All good! + } +}; + +void fContainsUnionWithSimpleUnionTest1() { + ContainsUnionWithSimpleUnionTest1(); +} + +class ContainsUnionWithSimpleUnionTest2 { + union UnionWithSimpleUnion { + union SimpleUnion { + float uf; + int ui; + char uc; + } usu; + long ul; + unsigned uu; + // TODO: we'd expect the note: {{uninitialized field 'this->u'}} + } u; // no-note + +public: + ContainsUnionWithSimpleUnionTest2() {} +}; + +void fContainsUnionWithSimpleUnionTest2() { + // TODO: we'd expect the warning: {{1 uninitialized field}} + ContainsUnionWithSimpleUnionTest2(); // no-warning +} + +//===----------------------------------------------------------------------===// +// Zero initialization tests. +//===----------------------------------------------------------------------===// + +struct GlobalVariableTest { + int i; + + GlobalVariableTest() {} +}; + +GlobalVariableTest gvt; // no-warning + +//===----------------------------------------------------------------------===// +// Copy and move constructor tests. +//===----------------------------------------------------------------------===// + +template <class T> +void funcToSquelchCompilerWarnings(const T &t); + +#ifdef PEDANTIC +struct CopyConstructorTest { + int i; // expected-note{{uninitialized field 'this->i'}} + + CopyConstructorTest() : i(1337) {} + CopyConstructorTest(const CopyConstructorTest &other) {} +}; + +void fCopyConstructorTest() { + CopyConstructorTest cct; + CopyConstructorTest copy = cct; // expected-warning{{1 uninitialized field}} + funcToSquelchCompilerWarnings(copy); +} +#else +struct CopyConstructorTest { + int i; + + CopyConstructorTest() : i(1337) {} + CopyConstructorTest(const CopyConstructorTest &other) {} +}; + +void fCopyConstructorTest() { + CopyConstructorTest cct; + CopyConstructorTest copy = cct; + funcToSquelchCompilerWarnings(copy); +} +#endif // PEDANTIC + +struct MoveConstructorTest { + // TODO: we'd expect the note: {{uninitialized field 'this->i'}} + int i; // no-note + + MoveConstructorTest() : i(1337) {} + MoveConstructorTest(const CopyConstructorTest &other) = delete; + MoveConstructorTest(const CopyConstructorTest &&other) {} +}; + +void fMoveConstructorTest() { + MoveConstructorTest cct; + // TODO: we'd expect the warning: {{1 uninitialized field}} + MoveConstructorTest copy(static_cast<MoveConstructorTest &&>(cct)); // no-warning + funcToSquelchCompilerWarnings(copy); +} + +//===----------------------------------------------------------------------===// +// Array tests. +//===----------------------------------------------------------------------===// + +struct IntArrayTest { + int arr[256]; + + IntArrayTest() { + // All good! + } +}; + +void fIntArrayTest() { + IntArrayTest(); +} + +struct RecordTypeArrayTest { + struct RecordType { + int x, y; + } arr[256]; + + RecordTypeArrayTest() { + // All good! + } +}; + +void fRecordTypeArrayTest() { + RecordTypeArrayTest(); +} + +template <class T> +class CharArrayPointerTest { + T *t; // no-crash + +public: + CharArrayPointerTest(T *t, int) : t(t) {} +}; + +void fCharArrayPointerTest() { + char str[16] = "012345678912345"; + CharArrayPointerTest<char[16]>(&str, int()); +} + +//===----------------------------------------------------------------------===// +// Memset tests. +//===----------------------------------------------------------------------===// + +struct MemsetTest1 { + int a, b, c; + + MemsetTest1() { + __builtin_memset(this, 0, sizeof(decltype(*this))); + } +}; + +void fMemsetTest1() { + MemsetTest1(); +} + +struct MemsetTest2 { + int a; + + MemsetTest2() { + __builtin_memset(&a, 0, sizeof(int)); + } +}; + +void fMemsetTest2() { + MemsetTest2(); +} + +//===----------------------------------------------------------------------===// +// Lambda tests. +//===----------------------------------------------------------------------===// + +template <class Callable> +struct LambdaTest1 { + Callable functor; + + LambdaTest1(const Callable &functor, int) : functor(functor) { + // All good! + } +}; + +void fLambdaTest1() { + auto isEven = [](int a) { return a % 2 == 0; }; + LambdaTest1<decltype(isEven)>(isEven, int()); +} + +#ifdef PEDANTIC +template <class Callable> +struct LambdaTest2 { + Callable functor; + + LambdaTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}} +}; + +void fLambdaTest2() { + int b; + auto equals = [&b](int a) { return a == b; }; // expected-note{{uninitialized field 'this->functor.'}} + LambdaTest2<decltype(equals)>(equals, int()); +} +#else +template <class Callable> +struct LambdaTest2 { + Callable functor; + + LambdaTest2(const Callable &functor, int) : functor(functor) {} +}; + +void fLambdaTest2() { + int b; + auto equals = [&b](int a) { return a == b; }; + LambdaTest2<decltype(equals)>(equals, int()); +} +#endif //PEDANTIC + +#ifdef PEDANTIC +namespace LT3Detail { + +struct RecordType { + int x; // expected-note{{uninitialized field 'this->functor..x'}} + int y; // expected-note{{uninitialized field 'this->functor..y'}} +}; + +} // namespace LT3Detail +template <class Callable> +struct LambdaTest3 { + Callable functor; + + LambdaTest3(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized fields}} +}; + +void fLambdaTest3() { + LT3Detail::RecordType rec1; + auto equals = [&rec1](LT3Detail::RecordType rec2) { + return rec1.x == rec2.x; + }; + LambdaTest3<decltype(equals)>(equals, int()); +} +#else +namespace LT3Detail { + +struct RecordType { + int x; + int y; +}; + +} // namespace LT3Detail +template <class Callable> +struct LambdaTest3 { + Callable functor; + + LambdaTest3(const Callable &functor, int) : functor(functor) {} +}; + +void fLambdaTest3() { + LT3Detail::RecordType rec1; + auto equals = [&rec1](LT3Detail::RecordType rec2) { + return rec1.x == rec2.x; + }; + LambdaTest3<decltype(equals)>(equals, int()); +} +#endif //PEDANTIC + +//===----------------------------------------------------------------------===// +// System header tests. +//===----------------------------------------------------------------------===// + +#include "Inputs/system-header-simulator-for-cxx-uninitialized-object.h" + +struct SystemHeaderTest1 { + RecordInSystemHeader rec; // defined in the system header simulator + + SystemHeaderTest1() { + // All good! + } +}; + +void fSystemHeaderTest1() { + SystemHeaderTest1(); +} + +#ifdef PEDANTIC +struct SystemHeaderTest2 { + struct RecordType { + int x; // expected-note{{uninitialized field 'this->container.t.x}} + int y; // expected-note{{uninitialized field 'this->container.t.y}} + }; + ContainerInSystemHeader<RecordType> container; + + SystemHeaderTest2(RecordType &rec, int) : container(rec) {} // expected-warning{{2 uninitialized fields}} +}; + +void fSystemHeaderTest2() { + SystemHeaderTest2::RecordType rec; + SystemHeaderTest2(rec, int()); +} +#else +struct SystemHeaderTest2 { + struct RecordType { + int x; + int y; + }; + ContainerInSystemHeader<RecordType> container; + + SystemHeaderTest2(RecordType &rec, int) : container(rec) {} +}; + +void fSystemHeaderTest2() { + SystemHeaderTest2::RecordType rec; + SystemHeaderTest2(rec, int()); +} +#endif //PEDANTIC + +//===----------------------------------------------------------------------===// +// Incomplete type tests. +//===----------------------------------------------------------------------===// + +struct IncompleteTypeTest1 { + struct RecordType; + // no-crash + RecordType *recptr; // expected-note{{uninitialized pointer 'this->recptr}} + int dontGetFilteredByNonPedanticMode = 0; + + IncompleteTypeTest1() {} // expected-warning{{1 uninitialized field}} +}; + +void fIncompleteTypeTest1() { + IncompleteTypeTest1(); +} + +struct IncompleteTypeTest2 { + struct RecordType; + RecordType *recptr; // no-crash + int dontGetFilteredByNonPedanticMode = 0; + + RecordType *recordTypeFactory(); + + IncompleteTypeTest2() : recptr(recordTypeFactory()) {} +}; + +void fIncompleteTypeTest2() { + IncompleteTypeTest2(); +} + +struct IncompleteTypeTest3 { + struct RecordType; + RecordType &recref; // no-crash + int dontGetFilteredByNonPedanticMode = 0; + + RecordType &recordTypeFactory(); + + IncompleteTypeTest3() : recref(recordTypeFactory()) {} +}; + +void fIncompleteTypeTest3() { + IncompleteTypeTest3(); +} + +//===----------------------------------------------------------------------===// +// Builtin type or enumeration type related tests. +//===----------------------------------------------------------------------===// + +struct IntegralTypeTest { + int a; // expected-note{{uninitialized field 'this->a'}} + int dontGetFilteredByNonPedanticMode = 0; + + IntegralTypeTest() {} // expected-warning{{1 uninitialized field}} +}; + +void fIntegralTypeTest() { + IntegralTypeTest(); +} + +struct FloatingTypeTest { + float a; // expected-note{{uninitialized field 'this->a'}} + int dontGetFilteredByNonPedanticMode = 0; + + FloatingTypeTest() {} // expected-warning{{1 uninitialized field}} +}; + +void fFloatingTypeTest() { + FloatingTypeTest(); +} + +struct NullptrTypeTypeTest { + decltype(nullptr) a; // expected-note{{uninitialized field 'this->a'}} + int dontGetFilteredByNonPedanticMode = 0; + + NullptrTypeTypeTest() {} // expected-warning{{1 uninitialized field}} +}; + +void fNullptrTypeTypeTest() { + NullptrTypeTypeTest(); +} + +struct EnumTest { + enum Enum { + A, + B + } enum1; // expected-note{{uninitialized field 'this->enum1'}} + enum class Enum2 { + A, + B + } enum2; // expected-note{{uninitialized field 'this->enum2'}} + int dontGetFilteredByNonPedanticMode = 0; + + EnumTest() {} // expected-warning{{2 uninitialized fields}} +}; + +void fEnumTest() { + EnumTest(); +} + +//===----------------------------------------------------------------------===// +// Tests for constructor calls within another cunstructor, without the two +// records being in any relation. +//===----------------------------------------------------------------------===// + +void halt() __attribute__((__noreturn__)); +void assert(int b) { + if (!b) + halt(); +} + +// While a singleton would make more sense as a static variable, that would zero +// initialize all of its fields, hence the not too practical implementation. +struct Singleton { + // TODO: we'd expect the note: {{uninitialized field 'this->i'}} + int i; // no-note + + Singleton() { + assert(!isInstantiated); + // TODO: we'd expect the warning: {{1 uninitialized field}} + isInstantiated = true; // no-warning + } + + ~Singleton() { + isInstantiated = false; + } + + static bool isInstantiated; +}; + +bool Singleton::isInstantiated = false; + +struct SingletonTest { + int dontGetFilteredByNonPedanticMode = 0; + + SingletonTest() { + Singleton(); + } +}; + +void fSingletonTest() { + SingletonTest(); +} + +//===----------------------------------------------------------------------===// +// C++11 member initializer tests. +//===----------------------------------------------------------------------===// + +struct CXX11MemberInitTest1 { + int a = 3; + int b; + CXX11MemberInitTest1() : b(2) { + // All good! + } +}; + +void fCXX11MemberInitTest1() { + CXX11MemberInitTest1(); +} + +struct CXX11MemberInitTest2 { + struct RecordType { + // TODO: we'd expect the note: {{uninitialized field 'this->rec.a'}} + int a; // no-note + // TODO: we'd expect the note: {{uninitialized field 'this->rec.b'}} + int b; // no-note + + RecordType(int) {} + }; + + RecordType rec = RecordType(int()); + int dontGetFilteredByNonPedanticMode = 0; + + CXX11MemberInitTest2() {} +}; + +void fCXX11MemberInitTest2() { + // TODO: we'd expect the warning: {{2 uninitializeds field}} + CXX11MemberInitTest2(); // no-warning +} |