r296326 - [analyzer] clarify 'result is garbage value' when it is out of bounds
Daniel Marjamaki via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 27 02:44:26 PST 2017
Author: danielmarjamaki
Date: Mon Feb 27 04:44:24 2017
New Revision: 296326
URL: http://llvm.org/viewvc/llvm-project?rev=296326&view=rev
Log:
[analyzer] clarify 'result is garbage value' when it is out of bounds
Differential Revision: https://reviews.llvm.org/D28278
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
cfe/trunk/test/Analysis/uninit-vals-ps.c
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp?rev=296326&r1=296325&r2=296326&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp Mon Feb 27 04:44:24 2017
@@ -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(c
<< " 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.
Modified: cfe/trunk/test/Analysis/uninit-vals-ps.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps.c?rev=296326&r1=296325&r2=296326&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps.c Mon Feb 27 04:44:24 2017
@@ -57,6 +57,12 @@ int f5(void) {
return s.x; // no-warning
}
+void f6(int x) {
+ int a[20];
+ if (x == 25) {}
+ if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
+}
+
int ret_uninit() {
int i;
int *p = &i;
More information about the cfe-commits
mailing list