diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-08-30 19:17:26 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-08-30 19:17:26 +0000 |
commit | e600025528eaa1c43e5084bab219f8f467b4731e (patch) | |
tree | dba522f70a20da7cc775891bad2177eedd4b245b | |
parent | 525dc284b4ee066b33ae76de5e6467d2191da442 (diff) | |
download | bcm5719-llvm-e600025528eaa1c43e5084bab219f8f467b4731e.tar.gz bcm5719-llvm-e600025528eaa1c43e5084bab219f8f467b4731e.zip |
[analyzer] Treat the rvalue of a forward-declared struct as Unknown.
This will never happen in the analyzed code code, but can happen for checkers
that over-eagerly dereference pointers without checking that it's safe.
UnknownVal is a harmless enough value to get back.
Fixes an issue added in r189590, caught by our internal buildbot.
llvm-svn: 189688
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 2 | ||||
-rw-r--r-- | clang/test/Analysis/taint-tester.cpp | 10 |
2 files changed, 10 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 8bc16bd4191..dd416f63666 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1843,7 +1843,7 @@ static bool isRecordEmpty(const RecordDecl *RD) { SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B, const TypedValueRegion *R) { const RecordDecl *RD = R->getValueType()->castAs<RecordType>()->getDecl(); - if (isRecordEmpty(RD)) + if (!RD->getDefinition() || isRecordEmpty(RD)) return UnknownVal(); return createLazyBinding(B, R); diff --git a/clang/test/Analysis/taint-tester.cpp b/clang/test/Analysis/taint-tester.cpp index f97eefb950e..ca7b729f269 100644 --- a/clang/test/Analysis/taint-tester.cpp +++ b/clang/test/Analysis/taint-tester.cpp @@ -6,7 +6,8 @@ typedef __typeof(sizeof(int)) size_t; extern FILE *stdin; typedef long ssize_t; ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict); -int printf(const char * __restrict, ...); +int printf(const char * __restrict, ...); +int snprintf(char *, size_t, const char *, ...); void free(void *ptr); struct GetLineTestStruct { @@ -25,3 +26,10 @@ void getlineTest(void) { } free(line); } + +class opaque; +void testOpaqueClass(opaque *obj) { + char buf[20]; + snprintf(buf, 20, "%p", obj); // don't crash trying to load *obj +} + |