BasicConstraintManager:
- Fix nonsensical logic in AssumeSymLE. When comparing 'sym <= constant' and the constant is the minimum integer value, add the constraint that 'sym == constant' when the path is deemed feasible. All other cases are feasible. - Improve AssumeSymLT to address <rdar://problem/6407949>. When comparing 'sym < constant' and constant is the minimum integer value we know the path is infeasible. - Add test case for <rdar://problem/6407949>. llvm-svn: 60489
This commit is contained in:
parent
3f86b51333
commit
f935cfe277
|
|
@ -313,6 +313,13 @@ const GRState*
|
||||||
BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolID sym,
|
BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolID sym,
|
||||||
const llvm::APSInt& V, bool& isFeasible) {
|
const llvm::APSInt& V, bool& isFeasible) {
|
||||||
|
|
||||||
|
// Is 'V' the smallest possible value?
|
||||||
|
if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
|
||||||
|
// sym cannot be any value less than 'V'. This path is infeasible.
|
||||||
|
isFeasible = false;
|
||||||
|
return St;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: For now have assuming x < y be the same as assuming sym != V;
|
// FIXME: For now have assuming x < y be the same as assuming sym != V;
|
||||||
return AssumeSymNE(St, sym, V, isFeasible);
|
return AssumeSymNE(St, sym, V, isFeasible);
|
||||||
}
|
}
|
||||||
|
|
@ -345,16 +352,27 @@ const GRState*
|
||||||
BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
|
BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
|
||||||
const llvm::APSInt& V, bool& isFeasible) {
|
const llvm::APSInt& V, bool& isFeasible) {
|
||||||
|
|
||||||
// FIXME: Primitive logic for now. Only reject a path if the value of
|
// Reject a path if the value of sym is a constant X and !(X <= V).
|
||||||
// sym is a constant X and !(X <= V).
|
|
||||||
|
|
||||||
if (const llvm::APSInt* X = getSymVal(St, sym)) {
|
if (const llvm::APSInt* X = getSymVal(St, sym)) {
|
||||||
isFeasible = *X <= V;
|
isFeasible = *X <= V;
|
||||||
return St;
|
return St;
|
||||||
}
|
}
|
||||||
|
|
||||||
isFeasible = !isNotEqual(St, sym, V) ||
|
// Sym is not a constant, but it is worth looking to see if V is the
|
||||||
(V != llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned()));
|
// minimum integer value.
|
||||||
|
if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
|
||||||
|
// If we know that sym != V, then this condition is infeasible since
|
||||||
|
// there is no other value less than V.
|
||||||
|
isFeasible = !isNotEqual(St, sym, V);
|
||||||
|
|
||||||
|
// If the path is still feasible then as a consequence we know that
|
||||||
|
// 'sym == V' because we cannot have 'sym < V' (no smaller values).
|
||||||
|
// Add this constraint.
|
||||||
|
if (isFeasible)
|
||||||
|
return AddEQ(St, sym, V);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
isFeasible = true;
|
||||||
|
|
||||||
return St;
|
return St;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,3 +134,13 @@ int* f10(int* p, signed char x, int y) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test case from <rdar://problem/6407949>
|
||||||
|
void f11(unsigned i) {
|
||||||
|
int *x = 0;
|
||||||
|
if (i >= 0) {
|
||||||
|
// always true
|
||||||
|
} else {
|
||||||
|
*x = 42; // no-warning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue