Fixed logic error in BasicConstraintManager pointed out by Zhongxing Xu.

For checking if a symbol >= value, we need to check if symbol == value || symbol
> value. When checking symbol > value and we know that symbol != value, the path
is infeasible only if value == maximum integer.

For checking if a symbol <= value, we need to check if symbol == value || symbol
< value. When checking symbol < value and we know that symbol != value, the path
is infeasible only if value == minimum integer.

Updated test case exercising this logic: we only prune paths if the values are
unsigned.

llvm-svn: 56354
This commit is contained in:
Ted Kremenek 2008-09-19 18:00:36 +00:00
parent a7b034463e
commit 34bfd8a490
2 changed files with 11 additions and 24 deletions

View File

@ -320,24 +320,9 @@ BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolID sym,
return St;
}
// sym is not a constant, but it might be not-equal to a constant.
// Observe: V >= sym is the same as sym <= V.
// check: is sym != V?
// check: is sym > V?
// if both are true, the path is infeasible.
if (isNotEqual(St, sym, V)) {
// Is sym > V?
//
// We're not doing heavy range analysis yet, so all we can accurately
// reason about are the edge cases.
//
// If V == 0, since we know that sym != V, we also know that sym > V.
isFeasible = V != 0;
}
else
isFeasible = true;
isFeasible = !isNotEqual(St, sym, V) ||
(V != llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned()));
return St;
}
@ -352,8 +337,10 @@ BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
isFeasible = *X <= V;
return St;
}
isFeasible = true;
isFeasible = !isNotEqual(St, sym, V) ||
(V != llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned()));
return St;
}

View File

@ -91,21 +91,21 @@ int f8(int *p, int *q) {
int* qux();
int f9(int len) {
int f9(unsigned len) {
assert (len != 0);
int *p = 0;
for (int i = 0; i < len; ++i)
for (unsigned i = 0; i < len; ++i)
p = qux(i);
return *p++; // no-warning
}
int f9b(int len) {
int f9b(unsigned len) {
assert (len > 0); // note use of '>'
int *p = 0;
for (int i = 0; i < len; ++i)
for (unsigned i = 0; i < len; ++i)
p = qux(i);
return *p++; // no-warning