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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits