danielmarjamaki updated this revision to Diff 89540.
danielmarjamaki added a comment.

Making the error message more precise.


https://reviews.llvm.org/D28278

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


Index: test/Analysis/uninit-vals-ps.c
===================================================================
--- test/Analysis/uninit-vals-ps.c
+++ test/Analysis/uninit-vals-ps.c
@@ -57,6 +57,12 @@
   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;
Index: lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -73,10 +73,31 @@
     }
 
     if (Ex) {
+      bool ArrayIndexOutOfBounds = false;
+      if (isa<ArraySubscriptExpr>(Ex)) {
+        SVal Loc = state->getSVal(Ex,LCtx);
+        if (Loc.isValid()) {
+          const MemRegion *MR = Loc.castAs<loc::MemRegionVal>().getRegion();
+          if (const ElementRegion *ER = dyn_cast<ElementRegion>(MR)) {
+            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);
+            if (StOutBound && !StInBound) {
+              ArrayIndexOutOfBounds = true;
+            }
+          }
+        }
+      }
+
       OS << "The " << (isLeft ? "left" : "right")
          << " operand of '"
          << BinaryOperator::getOpcodeStr(B->getOpcode())
          << "' is a garbage value";
+      if (ArrayIndexOutOfBounds)
+        OS << " due to array index out of bounds";
     }
     else {
       // Neither operand was undefined, but the result is undefined.


Index: test/Analysis/uninit-vals-ps.c
===================================================================
--- test/Analysis/uninit-vals-ps.c
+++ test/Analysis/uninit-vals-ps.c
@@ -57,6 +57,12 @@
   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;
Index: lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -73,10 +73,31 @@
     }
 
     if (Ex) {
+      bool ArrayIndexOutOfBounds = false;
+      if (isa<ArraySubscriptExpr>(Ex)) {
+        SVal Loc = state->getSVal(Ex,LCtx);
+        if (Loc.isValid()) {
+          const MemRegion *MR = Loc.castAs<loc::MemRegionVal>().getRegion();
+          if (const ElementRegion *ER = dyn_cast<ElementRegion>(MR)) {
+            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);
+            if (StOutBound && !StInBound) {
+              ArrayIndexOutOfBounds = true;
+            }
+          }
+        }
+      }
+
       OS << "The " << (isLeft ? "left" : "right")
          << " operand of '"
          << BinaryOperator::getOpcodeStr(B->getOpcode())
          << "' is a garbage value";
+      if (ArrayIndexOutOfBounds)
+        OS << " due to array index out of bounds";
     }
     else {
       // Neither operand was undefined, but the result is undefined.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to