]> granicus.if.org Git - clang/commitdiff
[analyzer] clarify 'result is garbage value' when it is out of bounds
authorDaniel Marjamaki <daniel.marjamaki@evidente.se>
Mon, 27 Feb 2017 10:44:24 +0000 (10:44 +0000)
committerDaniel Marjamaki <daniel.marjamaki@evidente.se>
Mon, 27 Feb 2017 10:44:24 +0000 (10:44 +0000)
Differential Revision: https://reviews.llvm.org/D28278

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@296326 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
test/Analysis/uninit-vals-ps.c

index 38d2aa6d8f9deb252da05b4f0f611350f98d3580..f3c2ffc58662e74993fe5f9f38c723230496d18b 100644 (file)
@@ -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.
index ad40b15502e46a32465e808f3ee824f359705bfe..83b1eb14b1e4607b85a38c12884905bffa6219de 100644 (file)
@@ -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;