[cfe-commits] r129366 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp test/Analysis/out-of-bounds.c
Ted Kremenek
kremenek at apple.com
Tue Apr 12 10:21:33 PDT 2011
Author: kremenek
Date: Tue Apr 12 12:21:33 2011
New Revision: 129366
URL: http://llvm.org/viewvc/llvm-project?rev=129366&view=rev
Log:
ArrayBoundCheckerV2: don't arbitrarily warn about indexing before the 0-index of a symbolic region. In many cases that isn't really the base offset.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
cfe/trunk/test/Analysis/out-of-bounds.c
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp?rev=129366&r1=129365&r2=129366&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp Tue Apr 12 12:21:33 2011
@@ -62,6 +62,22 @@
};
}
+static SVal computeExtentBegin(SValBuilder &svalBuilder,
+ const MemRegion *region) {
+ while (true)
+ switch (region->getKind()) {
+ default:
+ return svalBuilder.makeZeroArrayIndex();
+ case MemRegion::SymbolicRegionKind:
+ // FIXME: improve this later by tracking symbolic lower bounds
+ // for symbolic regions.
+ return UnknownVal();
+ case MemRegion::ElementRegionKind:
+ region = cast<SubRegion>(region)->getSuperRegion();
+ continue;
+ }
+}
+
void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
CheckerContext &checkerContext) const {
@@ -84,31 +100,36 @@
if (!rawOffset.getRegion())
return;
- // CHECK LOWER BOUND: Is byteOffset < 0? If so, we are doing a load/store
+ // CHECK LOWER BOUND: Is byteOffset < extent begin?
+ // If so, we are doing a load/store
// before the first valid offset in the memory region.
- SVal lowerBound
- = svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(),
- svalBuilder.makeZeroArrayIndex(),
- svalBuilder.getConditionType());
+ SVal extentBegin = computeExtentBegin(svalBuilder, rawOffset.getRegion());
+
+ if (isa<NonLoc>(extentBegin)) {
+ SVal lowerBound
+ = svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(),
+ cast<NonLoc>(extentBegin),
+ svalBuilder.getConditionType());
- NonLoc *lowerBoundToCheck = dyn_cast<NonLoc>(&lowerBound);
- if (!lowerBoundToCheck)
- return;
+ NonLoc *lowerBoundToCheck = dyn_cast<NonLoc>(&lowerBound);
+ if (!lowerBoundToCheck)
+ return;
- const GRState *state_precedesLowerBound, *state_withinLowerBound;
- llvm::tie(state_precedesLowerBound, state_withinLowerBound) =
+ const GRState *state_precedesLowerBound, *state_withinLowerBound;
+ llvm::tie(state_precedesLowerBound, state_withinLowerBound) =
state->assume(*lowerBoundToCheck);
- // Are we constrained enough to definitely precede the lower bound?
- if (state_precedesLowerBound && !state_withinLowerBound) {
- reportOOB(checkerContext, state_precedesLowerBound, OOB_Precedes);
- return;
- }
+ // Are we constrained enough to definitely precede the lower bound?
+ if (state_precedesLowerBound && !state_withinLowerBound) {
+ reportOOB(checkerContext, state_precedesLowerBound, OOB_Precedes);
+ return;
+ }
- // Otherwise, assume the constraint of the lower bound.
- assert(state_withinLowerBound);
- state = state_withinLowerBound;
+ // Otherwise, assume the constraint of the lower bound.
+ assert(state_withinLowerBound);
+ state = state_withinLowerBound;
+ }
do {
// CHECK UPPER BOUND: Is byteOffset >= extent(baseRegion)? If so,
@@ -232,9 +253,11 @@
while (region) {
switch (region->getKind()) {
default: {
- if (const SubRegion *subReg = dyn_cast<SubRegion>(region))
+ if (const SubRegion *subReg = dyn_cast<SubRegion>(region)) {
+ offset = getValue(offset, svalBuilder);
if (!offset.isUnknownOrUndef())
return RegionRawOffsetV2(subReg, offset);
+ }
return RegionRawOffsetV2();
}
case MemRegion::ElementRegionKind: {
Modified: cfe/trunk/test/Analysis/out-of-bounds.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/out-of-bounds.c?rev=129366&r1=129365&r2=129366&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/out-of-bounds.c (original)
+++ cfe/trunk/test/Analysis/out-of-bounds.c Tue Apr 12 12:21:33 2011
@@ -146,3 +146,12 @@
if (x > 99)
buf[x] = 1;
}
+
+// Don't warn when indexing below the start of a symbolic region's whose
+// base extent we don't know.
+int *get_symbolic();
+void test_index_below_symboloc() {
+ int *buf = get_symbolic();
+ buf[-1] = 0; // no-warning;
+}
+
More information about the cfe-commits
mailing list