diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-12-03 18:56:12 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-12-03 18:56:12 +0000 |
commit | f935cfe277fbf839ba149b45b6d27418a8e16a8c (patch) | |
tree | 0a53ec64b2497778ea5366bd70b936c62100f7c6 /clang/lib/Analysis/BasicConstraintManager.cpp | |
parent | 3f86b5133363b95b751cc65bf420664d70df02e1 (diff) | |
download | bcm5719-llvm-f935cfe277fbf839ba149b45b6d27418a8e16a8c.tar.gz bcm5719-llvm-f935cfe277fbf839ba149b45b6d27418a8e16a8c.zip |
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
Diffstat (limited to 'clang/lib/Analysis/BasicConstraintManager.cpp')
-rw-r--r-- | clang/lib/Analysis/BasicConstraintManager.cpp | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp index 5ce95a1e565..c8065d18690 100644 --- a/clang/lib/Analysis/BasicConstraintManager.cpp +++ b/clang/lib/Analysis/BasicConstraintManager.cpp @@ -312,6 +312,13 @@ BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolID sym, const GRState* BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolID sym, 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; return AssumeSymNE(St, sym, V, isFeasible); @@ -345,17 +352,28 @@ const GRState* BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym, const llvm::APSInt& V, bool& isFeasible) { - // FIXME: Primitive logic for now. Only reject a path if the value of - // sym is a constant X and !(X <= V). - + // Reject a path if the value of sym is a constant X and !(X <= V). if (const llvm::APSInt* X = getSymVal(St, sym)) { isFeasible = *X <= V; return St; } - isFeasible = !isNotEqual(St, sym, V) || - (V != llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())); - + // Sym is not a constant, but it is worth looking to see if V is the + // 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; } |