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:
parent
a7b034463e
commit
34bfd8a490
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user