diff options
Diffstat (limited to 'test/Analysis/cxx-uninitialized-object-ptr-ref.cpp')
-rw-r--r-- | test/Analysis/cxx-uninitialized-object-ptr-ref.cpp | 233 |
1 files changed, 223 insertions, 10 deletions
diff --git a/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp b/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp index 1507098c5e757..edc594a0bf1ba 100644 --- a/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp +++ b/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp @@ -1,6 +1,11 @@ -// 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 \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: -std=c++11 -verify %s -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -std=c++11 -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \ +// RUN: -std=c++11 -verify %s //===----------------------------------------------------------------------===// // Concrete location tests. @@ -17,6 +22,24 @@ void fConcreteIntLocTest() { } //===----------------------------------------------------------------------===// +// nonloc::LocAsInteger tests. +//===----------------------------------------------------------------------===// + +using intptr_t = unsigned long long; + +struct LocAsIntegerTest { + intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast<char *>(this->ptr)'}} + int dontGetFilteredByNonPedanticMode = 0; + + LocAsIntegerTest(void *ptr) : ptr(reinterpret_cast<intptr_t>(ptr)) {} // expected-warning{{1 uninitialized field}} +}; + +void fLocAsIntegerTest() { + char c; + LocAsIntegerTest t(&c); +} + +//===----------------------------------------------------------------------===// // Null pointer tests. //===----------------------------------------------------------------------===// @@ -41,6 +64,50 @@ void fNullPtrTest() { } //===----------------------------------------------------------------------===// +// Alloca tests. +//===----------------------------------------------------------------------===// + +struct UntypedAllocaTest { + void *allocaPtr; + int dontGetFilteredByNonPedanticMode = 0; + + UntypedAllocaTest() : allocaPtr(__builtin_alloca(sizeof(int))) { + // All good! + } +}; + +void fUntypedAllocaTest() { + UntypedAllocaTest(); +} + +struct TypedAllocaTest1 { + int *allocaPtr; // expected-note{{uninitialized pointee 'this->allocaPtr'}} + int dontGetFilteredByNonPedanticMode = 0; + + TypedAllocaTest1() // expected-warning{{1 uninitialized field}} + : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) {} +}; + +void fTypedAllocaTest1() { + TypedAllocaTest1(); +} + +struct TypedAllocaTest2 { + int *allocaPtr; + int dontGetFilteredByNonPedanticMode = 0; + + TypedAllocaTest2() + : allocaPtr(static_cast<int *>(__builtin_alloca(sizeof(int)))) { + *allocaPtr = 55555; + // All good! + } +}; + +void fTypedAllocaTest2() { + TypedAllocaTest2(); +} + +//===----------------------------------------------------------------------===// // Heap pointer tests. //===----------------------------------------------------------------------===// @@ -189,13 +256,26 @@ void fCharPointerTest() { CharPointerTest(); } -struct CyclicPointerTest { - int *ptr; - CyclicPointerTest() : ptr(reinterpret_cast<int*>(&ptr)) {} +struct CyclicPointerTest1 { + int *ptr; // expected-note{{object references itself 'this->ptr'}} + int dontGetFilteredByNonPedanticMode = 0; + + CyclicPointerTest1() : ptr(reinterpret_cast<int *>(&ptr)) {} // expected-warning{{1 uninitialized field}} }; -void fCyclicPointerTest() { - CyclicPointerTest(); +void fCyclicPointerTest1() { + CyclicPointerTest1(); +} + +struct CyclicPointerTest2 { + int **pptr; // expected-note{{object references itself 'this->pptr'}} + int dontGetFilteredByNonPedanticMode = 0; + + CyclicPointerTest2() : pptr(reinterpret_cast<int **>(&pptr)) {} // expected-warning{{1 uninitialized field}} +}; + +void fCyclicPointerTest2() { + CyclicPointerTest2(); } //===----------------------------------------------------------------------===// @@ -277,16 +357,66 @@ void fVoidPointerLRefTest() { } struct CyclicVoidPointerTest { - void *vptr; // no-crash - - CyclicVoidPointerTest() : vptr(&vptr) {} + void *vptr; // expected-note{{object references itself 'this->vptr'}} + int dontGetFilteredByNonPedanticMode = 0; + CyclicVoidPointerTest() : vptr(&vptr) {} // expected-warning{{1 uninitialized field}} }; void fCyclicVoidPointerTest() { CyclicVoidPointerTest(); } +struct IntDynTypedVoidPointerTest1 { + void *vptr; // expected-note{{uninitialized pointee 'static_cast<int *>(this->vptr)'}} + int dontGetFilteredByNonPedanticMode = 0; + + IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // expected-warning{{1 uninitialized field}} +}; + +void fIntDynTypedVoidPointerTest1() { + int a; + IntDynTypedVoidPointerTest1 tmp(&a); +} + +struct RecordDynTypedVoidPointerTest { + struct RecordType { + int x; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}} + int y; // expected-note{{uninitialized field 'static_cast<struct RecordDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}} + }; + + void *vptr; + int dontGetFilteredByNonPedanticMode = 0; + + RecordDynTypedVoidPointerTest(void *vptr) : vptr(vptr) {} // expected-warning{{2 uninitialized fields}} +}; + +void fRecordDynTypedVoidPointerTest() { + RecordDynTypedVoidPointerTest::RecordType a; + RecordDynTypedVoidPointerTest tmp(&a); +} + +struct NestedNonVoidDynTypedVoidPointerTest { + struct RecordType { + int x; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->x'}} + int y; // expected-note{{uninitialized field 'static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->y'}} + void *vptr; // expected-note{{uninitialized pointee 'static_cast<char *>(static_cast<struct NestedNonVoidDynTypedVoidPointerTest::RecordType *>(this->vptr)->vptr)'}} + }; + + void *vptr; + int dontGetFilteredByNonPedanticMode = 0; + + NestedNonVoidDynTypedVoidPointerTest(void *vptr, void *c) : vptr(vptr) { + static_cast<RecordType *>(vptr)->vptr = c; // expected-warning{{3 uninitialized fields}} + } +}; + +void fNestedNonVoidDynTypedVoidPointerTest() { + NestedNonVoidDynTypedVoidPointerTest::RecordType a; + char c; + NestedNonVoidDynTypedVoidPointerTest tmp(&a, &c); +} + //===----------------------------------------------------------------------===// // Multipointer tests. //===----------------------------------------------------------------------===// @@ -404,6 +534,39 @@ void fMultiPointerTest3() { } //===----------------------------------------------------------------------===// +// Incomplete pointee tests. +//===----------------------------------------------------------------------===// + +class IncompleteType; + +struct IncompletePointeeTypeTest { + IncompleteType *pImpl; //no-crash + int dontGetFilteredByNonPedanticMode = 0; + + IncompletePointeeTypeTest(IncompleteType *A) : pImpl(A) {} +}; + +void fIncompletePointeeTypeTest(void *ptr) { + IncompletePointeeTypeTest(reinterpret_cast<IncompleteType *>(ptr)); +} + +//===----------------------------------------------------------------------===// +// Function pointer tests. +//===----------------------------------------------------------------------===// + +struct FunctionPointerWithDifferentDynTypeTest { + using Func1 = void *(*)(); + using Func2 = int *(*)(); + + Func1 f; // no-crash + FunctionPointerWithDifferentDynTypeTest(Func2 f) : f((Func1)f) {} +}; + +// Note that there isn't a function calling the constructor of +// FunctionPointerWithDifferentDynTypeTest, because a crash could only be +// reproduced without it. + +//===----------------------------------------------------------------------===// // Member pointer tests. //===----------------------------------------------------------------------===// @@ -578,6 +741,15 @@ void fCyclicList() { CyclicList(&n1, int()); } +struct RingListTest { + RingListTest *next; // no-crash + RingListTest() : next(this) {} +}; + +void fRingListTest() { + RingListTest(); +} + //===----------------------------------------------------------------------===// // Tests for classes containing references. //===----------------------------------------------------------------------===// @@ -693,3 +865,44 @@ void fReferenceTest5() { ReferenceTest4::RecordType c, d{37, 38}; ReferenceTest4(d, c); } + +//===----------------------------------------------------------------------===// +// Tests for objects containing multiple references to the same object. +//===----------------------------------------------------------------------===// + +struct IntMultipleReferenceToSameObjectTest { + int *iptr; // expected-note{{uninitialized pointee 'this->iptr'}} + int &iref; // no-note, pointee of this->iref was already reported + + int dontGetFilteredByNonPedanticMode = 0; + + IntMultipleReferenceToSameObjectTest(int *i) : iptr(i), iref(*i) {} // expected-warning{{1 uninitialized field}} +}; + +void fIntMultipleReferenceToSameObjectTest() { + int a; + IntMultipleReferenceToSameObjectTest Test(&a); +} + +struct IntReferenceWrapper1 { + int &a; // expected-note{{uninitialized pointee 'this->a'}} + + int dontGetFilteredByNonPedanticMode = 0; + + IntReferenceWrapper1(int &a) : a(a) {} // expected-warning{{1 uninitialized field}} +}; + +struct IntReferenceWrapper2 { + int &a; // no-note, pointee of this->a was already reported + + int dontGetFilteredByNonPedanticMode = 0; + + IntReferenceWrapper2(int &a) : a(a) {} // no-warning +}; + +void fMultipleObjectsReferencingTheSameObjectTest() { + int a; + + IntReferenceWrapper1 T1(a); + IntReferenceWrapper2 T2(a); +} |