summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
diff options
context:
space:
mode:
authorDaniel Marjamaki <daniel.marjamaki@evidente.se>2017-02-27 10:44:24 +0000
committerDaniel Marjamaki <daniel.marjamaki@evidente.se>2017-02-27 10:44:24 +0000
commite97838f49ef1413e67ab1d92502687d516cef8e4 (patch)
tree8ae7332a4c03b8bdb70530aea2a94e75685b1451 /clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
parentbc3fbe49c56801b861c3d69a145f13f970372ad1 (diff)
downloadbcm5719-llvm-e97838f49ef1413e67ab1d92502687d516cef8e4.tar.gz
bcm5719-llvm-e97838f49ef1413e67ab1d92502687d516cef8e4.zip
[analyzer] clarify 'result is garbage value' when it is out of bounds
Differential Revision: https://reviews.llvm.org/D28278 llvm-svn: 296326
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index 38d2aa6d8f9..f3c2ffc5866 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -35,6 +35,30 @@ public:
};
} // end anonymous namespace
+static bool isArrayIndexOutOfBounds(CheckerContext &C, const Expr *Ex) {
+ ProgramStateRef state = C.getState();
+ const LocationContext *LCtx = C.getLocationContext();
+
+ if (!isa<ArraySubscriptExpr>(Ex))
+ return false;
+
+ SVal Loc = state->getSVal(Ex, LCtx);
+ if (!Loc.isValid())
+ return false;
+
+ const MemRegion *MR = Loc.castAs<loc::MemRegionVal>().getRegion();
+ const ElementRegion *ER = dyn_cast<ElementRegion>(MR);
+ if (!ER)
+ return false;
+
+ DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
+ DefinedOrUnknownSVal NumElements = C.getStoreManager().getSizeInElements(
+ state, ER->getSuperRegion(), ER->getValueType());
+ ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
+ ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
+ return StOutBound && !StInBound;
+}
+
void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
CheckerContext &C) const {
ProgramStateRef state = C.getState();
@@ -77,6 +101,8 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
<< " operand of '"
<< BinaryOperator::getOpcodeStr(B->getOpcode())
<< "' is a garbage value";
+ if (isArrayIndexOutOfBounds(C, Ex))
+ OS << " due to array index out of bounds";
}
else {
// Neither operand was undefined, but the result is undefined.
OpenPOWER on IntegriCloud