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