diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2017-12-12 02:27:55 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2017-12-12 02:27:55 +0000 |
commit | 3ef5deb3a790daa46f8947bab33563001445197c (patch) | |
tree | ba615c1ae71a6a2b6df14622ee817f29d9137670 /clang/lib | |
parent | e8d85eaaa77e22142117e16a2c6922ca953ba4fe (diff) | |
download | bcm5719-llvm-3ef5deb3a790daa46f8947bab33563001445197c.tar.gz bcm5719-llvm-3ef5deb3a790daa46f8947bab33563001445197c.zip |
[analyzer] In getSVal() API, disable auto-detection of void type as char type.
This is a follow-up from r314910. When a checker developer attempts to
dereference a location in memory through ProgramState::getSVal(Loc) or
ProgramState::getSVal(const MemRegion *), without specifying the second
optional QualType parameter for the type of the value he tries to find at this
location, the type is auto-detected from location type. If the location
represents a value beyond a void pointer, we thought that auto-detecting the
type as 'char' is a good idea. However, in most practical cases, the correct
behavior would be to specify the type explicitly, as it is available from other
sources, and the few cases where we actually need to take a 'char' are
workarounds rather than an intended behavior. Therefore, try to fail with an
easy-to-understand assertion when asked to read from a void pointer location.
Differential Revision: https://reviews.llvm.org/D38801
llvm-svn: 320451
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | 2 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp | 17 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 5 |
3 files changed, 15 insertions, 9 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index 07285d27ed9..20a46843e23 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -179,7 +179,7 @@ bool CallAndMessageChecker::uninitRefOrPointer( if (const MemRegion *SValMemRegion = V.getAsRegion()) { const ProgramStateRef State = C.getState(); - const SVal PSV = State->getSVal(SValMemRegion); + const SVal PSV = State->getSVal(SValMemRegion, C.getASTContext().CharTy); if (PSV.isUndef()) { if (ExplodedNode *N = C.generateErrorNode()) { LazyInit_BT(BD, BT); diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index 883c6a66329..43966656cd8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -466,7 +466,7 @@ bool GenericTaintChecker::checkPre(const CallExpr *CE, CheckerContext &C) const{ } Optional<SVal> GenericTaintChecker::getPointedToSVal(CheckerContext &C, - const Expr* Arg) { + const Expr *Arg) { ProgramStateRef State = C.getState(); SVal AddrVal = State->getSVal(Arg->IgnoreParens(), C.getLocationContext()); if (AddrVal.isUnknownOrUndef()) @@ -476,9 +476,18 @@ Optional<SVal> GenericTaintChecker::getPointedToSVal(CheckerContext &C, if (!AddrLoc) return None; - const PointerType *ArgTy = - dyn_cast<PointerType>(Arg->getType().getCanonicalType().getTypePtr()); - return State->getSVal(*AddrLoc, ArgTy ? ArgTy->getPointeeType(): QualType()); + QualType ArgTy = Arg->getType().getCanonicalType(); + if (!ArgTy->isPointerType()) + return None; + + QualType ValTy = ArgTy->getPointeeType(); + + // Do not dereference void pointers. Treat them as byte pointers instead. + // FIXME: we might want to consider more than just the first byte. + if (ValTy->isVoidType()) + ValTy = C.getASTContext().CharTy; + + return State->getSVal(*AddrLoc, ValTy); } ProgramStateRef diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index ecb32cc378d..7f2a481c6b0 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1405,10 +1405,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) T = Ctx.VoidTy; } assert(!T.isNull() && "Unable to auto-detect binding type!"); - if (T->isVoidType()) { - // When trying to dereference a void pointer, read the first byte. - T = Ctx.CharTy; - } + assert(!T->isVoidType() && "Attempting to dereference a void pointer!"); MR = GetElementZeroRegion(cast<SubRegion>(MR), T); } |