| // 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 LambdaThisTest { |
| Callable functor; |
| |
| LambdaThisTest(const Callable &functor, int) : functor(functor) { |
| // All good! |
| } |
| }; |
| |
| struct HasCapturableThis { |
| void fLambdaThisTest() { |
| auto isEven = [this](int a) { return a % 2 == 0; }; // no-crash |
| LambdaThisTest<decltype(isEven)>(isEven, int()); |
| } |
| }; |
| |
| 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.b'}} |
| 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.rec1.x'}} |
| int y; // expected-note{{uninitialized field 'this->functor.rec1.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 |
| |
| template <class Callable> |
| struct MultipleLambdaCapturesTest1 { |
| Callable functor; |
| int dontGetFilteredByNonPedanticMode = 0; |
| |
| MultipleLambdaCapturesTest1(const Callable &functor, int) : functor(functor) {} // expected-warning{{2 uninitialized field}} |
| }; |
| |
| void fMultipleLambdaCapturesTest1() { |
| int b1, b2 = 3, b3; |
| auto equals = [&b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized field 'this->functor.b1'}} |
| // expected-note@-1{{uninitialized field 'this->functor.b3'}} |
| MultipleLambdaCapturesTest1<decltype(equals)>(equals, int()); |
| } |
| |
| template <class Callable> |
| struct MultipleLambdaCapturesTest2 { |
| Callable functor; |
| int dontGetFilteredByNonPedanticMode = 0; |
| |
| MultipleLambdaCapturesTest2(const Callable &functor, int) : functor(functor) {} // expected-warning{{1 uninitialized field}} |
| }; |
| |
| void fMultipleLambdaCapturesTest2() { |
| int b1, b2 = 3, b3; |
| auto equals = [b1, &b2, &b3](int a) { return a == b1 == b2 == b3; }; // expected-note{{uninitialized field 'this->functor.b3'}} |
| MultipleLambdaCapturesTest2<decltype(equals)>(equals, int()); |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // 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 |
| } |