diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-03-26 03:35:11 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-03-26 03:35:11 +0000 |
commit | e0e4ebf6bfca5a71b2344d8a1b748b852509279c (patch) | |
tree | ee78de68ac056d841a957b09b7a3c820fba17979 /lib/Analysis/SimpleConstraintManager.cpp | |
parent | 4cbe82c7c82ca0106f60296a60951d41f7d2ec7d (diff) |
analyzer infrastructure: make a bunch of changes to symbolic expressions that
Zhongxing and I discussed by email.
Main changes:
- Removed SymIntConstraintVal and SymIntConstraint
- Added SymExpr as a parent class to SymbolData, SymSymExpr, SymIntExpr
- Added nonloc::SymExprVal to wrap SymExpr
- SymbolRef is now just a typedef of 'const SymbolData*'
- Bunch of minor code cleanups in how some methods were invoked (no functionality change)
This changes are part of a long-term plan to have full symbolic expression
trees. This will be useful for lazily evaluating complicated expressions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67731 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/SimpleConstraintManager.cpp')
-rw-r--r-- | lib/Analysis/SimpleConstraintManager.cpp | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/lib/Analysis/SimpleConstraintManager.cpp b/lib/Analysis/SimpleConstraintManager.cpp index 50552c1144..904479c4c3 100644 --- a/lib/Analysis/SimpleConstraintManager.cpp +++ b/lib/Analysis/SimpleConstraintManager.cpp @@ -21,11 +21,35 @@ namespace clang { SimpleConstraintManager::~SimpleConstraintManager() {} bool SimpleConstraintManager::canReasonAbout(SVal X) const { - if (nonloc::SymbolVal* SymVal = dyn_cast<nonloc::SymbolVal>(&X)) { - const SymbolData& data - = getSymbolManager().getSymbolData(SymVal->getSymbol()); - return !(data.getKind() == SymbolData::SymIntKind || - data.getKind() == SymbolData::SymSymKind ); + if (nonloc::SymExprVal *SymVal = dyn_cast<nonloc::SymExprVal>(&X)) { + const SymExpr *SE = SymVal->getSymbolicExpression(); + + if (isa<SymbolData>(SE)) + return true; + + if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) { + switch (SIE->getOpcode()) { + // We don't reason yet about bitwise-constraints on symbolic values. + case BinaryOperator::And: + case BinaryOperator::Or: + case BinaryOperator::Xor: + return false; + // We don't reason yet about arithmetic constraints on symbolic values. + case BinaryOperator::Mul: + case BinaryOperator::Div: + case BinaryOperator::Rem: + case BinaryOperator::Add: + case BinaryOperator::Sub: + case BinaryOperator::Shl: + case BinaryOperator::Shr: + return false; + // All other cases. + default: + return true; + } + } + + return false; } return true; @@ -150,11 +174,14 @@ SimpleConstraintManager::AssumeAux(const GRState* St,NonLoc Cond, return AssumeSymEQ(St, sym, BasicVals.getValue(0, T), isFeasible); } - case nonloc::SymIntConstraintValKind: - return - AssumeSymInt(St, Assumption, - cast<nonloc::SymIntConstraintVal>(Cond).getConstraint(), - isFeasible); + case nonloc::SymExprValKind: { + nonloc::SymExprVal V = cast<nonloc::SymExprVal>(Cond); + if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression())) + return AssumeSymInt(St, Assumption, SE, isFeasible); + + isFeasible = true; + return St; + } case nonloc::ConcreteIntKind: { bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0; @@ -170,50 +197,43 @@ SimpleConstraintManager::AssumeAux(const GRState* St,NonLoc Cond, const GRState* SimpleConstraintManager::AssumeSymInt(const GRState* St, bool Assumption, - const SymIntConstraint& C, - bool& isFeasible) { + const SymIntExpr *SE, bool& isFeasible) { + - switch (C.getOpcode()) { + // Here we assume that LHS is a symbol. This is consistent with the + // rest of the constraint manager logic. + SymbolRef Sym = cast<SymbolData>(SE->getLHS()); + const llvm::APSInt &Int = SE->getRHS(); + + switch (SE->getOpcode()) { default: // No logic yet for other operators. isFeasible = true; return St; case BinaryOperator::EQ: - if (Assumption) - return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible); - else - return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible); + return Assumption ? AssumeSymEQ(St, Sym, Int, isFeasible) + : AssumeSymNE(St, Sym, Int, isFeasible); case BinaryOperator::NE: - if (Assumption) - return AssumeSymNE(St, C.getSymbol(), C.getInt(), isFeasible); - else - return AssumeSymEQ(St, C.getSymbol(), C.getInt(), isFeasible); + return Assumption ? AssumeSymNE(St, Sym, Int, isFeasible) + : AssumeSymEQ(St, Sym, Int, isFeasible); case BinaryOperator::GT: - if (Assumption) - return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible); - else - return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible); + return Assumption ? AssumeSymGT(St, Sym, Int, isFeasible) + : AssumeSymLE(St, Sym, Int, isFeasible); case BinaryOperator::GE: - if (Assumption) - return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible); - else - return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible); + return Assumption ? AssumeSymGE(St, Sym, Int, isFeasible) + : AssumeSymLT(St, Sym, Int, isFeasible); case BinaryOperator::LT: - if (Assumption) - return AssumeSymLT(St, C.getSymbol(), C.getInt(), isFeasible); - else - return AssumeSymGE(St, C.getSymbol(), C.getInt(), isFeasible); + return Assumption ? AssumeSymLT(St, Sym, Int, isFeasible) + : AssumeSymGE(St, Sym, Int, isFeasible); case BinaryOperator::LE: - if (Assumption) - return AssumeSymLE(St, C.getSymbol(), C.getInt(), isFeasible); - else - return AssumeSymGT(St, C.getSymbol(), C.getInt(), isFeasible); + return Assumption ? AssumeSymLE(St, Sym, Int, isFeasible) + : AssumeSymGT(St, Sym, Int, isFeasible); } // end switch } |