From 4b4a06c6798637cd119e355c9ff31073ce6e3acc Mon Sep 17 00:00:00 2001 From: Daniel Marjamaki Date: Mon, 27 Feb 2017 10:44:24 +0000 Subject: [PATCH] [analyzer] clarify 'result is garbage value' when it is out of bounds Differential Revision: https://reviews.llvm.org/D28278 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@296326 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/UndefResultChecker.cpp | 26 +++++++++++++++++++ test/Analysis/uninit-vals-ps.c | 6 +++++ 2 files changed, 32 insertions(+) diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp index 38d2aa6d8f..f3c2ffc586 100644 --- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp +++ b/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(Ex)) + return false; + + SVal Loc = state->getSVal(Ex, LCtx); + if (!Loc.isValid()) + return false; + + const MemRegion *MR = Loc.castAs().getRegion(); + const ElementRegion *ER = dyn_cast(MR); + if (!ER) + return false; + + DefinedOrUnknownSVal Idx = ER->getIndex().castAs(); + 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. diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c index ad40b15502..83b1eb14b1 100644 --- a/test/Analysis/uninit-vals-ps.c +++ b/test/Analysis/uninit-vals-ps.c @@ -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; -- 2.40.0