diff options
author | Kristof Umann <dkszelethus@gmail.com> | 2018-08-08 13:18:53 +0000 |
---|---|---|
committer | Kristof Umann <dkszelethus@gmail.com> | 2018-08-08 13:18:53 +0000 |
commit | ef9af05539d9cb7f11346588fbe719f30712b638 (patch) | |
tree | 360fbb39fb50785dc5784180587473fee6d959da /clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp | |
parent | db5908deb964b81234a59ab477b460275552c038 (diff) | |
download | bcm5719-llvm-ef9af05539d9cb7f11346588fbe719f30712b638.tar.gz bcm5719-llvm-ef9af05539d9cb7f11346588fbe719f30712b638.zip |
[analyzer][UninitializedObjectChecker] Pointer/reference objects are dereferenced according to dynamic type
This patch fixed an issue where the dynamic type of pointer/reference
object was known by the analyzer, but wasn't obtained in the checker,
which resulted in false negatives. This should also increase reliability
of the checker, as derefencing is always done now according to the
dynamic type (even if that happens to be the same as the static type).
Special thanks to Artem Degrachev for setting me on the right track.
Differential Revision: https://reviews.llvm.org/D49199
llvm-svn: 339240
Diffstat (limited to 'clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp')
-rw-r--r-- | clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp b/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp index bfffc800bc4..2d5ebff5361 100644 --- a/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp +++ b/clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp @@ -196,7 +196,7 @@ void fCharPointerTest() { struct CyclicPointerTest { int *ptr; - CyclicPointerTest() : ptr(reinterpret_cast<int*>(&ptr)) {} + CyclicPointerTest() : ptr(reinterpret_cast<int *>(&ptr)) {} }; void fCyclicPointerTest() { @@ -285,13 +285,62 @@ struct CyclicVoidPointerTest { void *vptr; // no-crash CyclicVoidPointerTest() : vptr(&vptr) {} - }; void fCyclicVoidPointerTest() { CyclicVoidPointerTest(); } +struct IntDynTypedVoidPointerTest1 { + void *vptr; // expected-note{{uninitialized pointee '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 'this->vptr->x'}} + int y; // expected-note{{uninitialized field '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 'this->vptr->x'}} + int y; // expected-note{{uninitialized field 'this->vptr->y'}} + void *vptr; // expected-note{{uninitialized pointee '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. //===----------------------------------------------------------------------===// |