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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits