aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Analysis/PathSensitive/ConstraintManager.h21
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h19
-rw-r--r--include/clang/Analysis/PathSensitive/GRState.h121
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h8
-rw-r--r--lib/Analysis/BasicConstraintManager.cpp160
-rw-r--r--lib/Analysis/CFRefCount.cpp13
-rw-r--r--lib/Analysis/GRExprEngine.cpp194
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp13
-rw-r--r--lib/Analysis/RangeConstraintManager.cpp17
-rw-r--r--lib/Analysis/SimpleConstraintManager.cpp183
-rw-r--r--lib/Analysis/SimpleConstraintManager.h78
11 files changed, 368 insertions, 459 deletions
diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h
index c8e5e85c8a..eb519e0e74 100644
--- a/include/clang/Analysis/PathSensitive/ConstraintManager.h
+++ b/include/clang/Analysis/PathSensitive/ConstraintManager.h
@@ -30,26 +30,25 @@ class SVal;
class ConstraintManager {
public:
virtual ~ConstraintManager();
- virtual const GRState* Assume(const GRState* St, SVal Cond,
- bool Assumption, bool& isFeasible) = 0;
+ virtual const GRState *Assume(const GRState *state, SVal Cond,
+ bool Assumption) = 0;
- virtual const GRState* AssumeInBound(const GRState* St, SVal Idx,
- SVal UpperBound, bool Assumption,
- bool& isFeasible) = 0;
+ virtual const GRState *AssumeInBound(const GRState *state, SVal Idx,
+ SVal UpperBound, bool Assumption) = 0;
- virtual const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym)
- const = 0;
+ virtual const llvm::APSInt* getSymVal(const GRState *state,
+ SymbolRef sym) const = 0;
- virtual bool isEqual(const GRState* St, SymbolRef sym,
+ virtual bool isEqual(const GRState *state, SymbolRef sym,
const llvm::APSInt& V) const = 0;
- virtual const GRState* RemoveDeadBindings(const GRState* St,
+ virtual const GRState *RemoveDeadBindings(const GRState *state,
SymbolReaper& SymReaper) = 0;
- virtual void print(const GRState* St, std::ostream& Out,
+ virtual void print(const GRState *state, std::ostream& Out,
const char* nl, const char *sep) = 0;
- virtual void EndPath(const GRState* St) {}
+ virtual void EndPath(const GRState *state) {}
/// canReasonAbout - Not all ConstraintManagers can accurately reason about
/// all SVal values. This method returns true if the ConstraintManager can
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 2068b1beaa..6cf49d0db1 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -520,24 +520,7 @@ protected:
inline NonLoc MakeConstantVal(uint64_t X, Expr* Ex) {
return NonLoc::MakeVal(getBasicVals(), X, Ex->getType());
- }
-
- /// Assume - Create new state by assuming that a given expression
- /// is true or false.
- const GRState* Assume(const GRState* St, SVal Cond, bool Assumption,
- bool& isFeasible) {
- return StateMgr.Assume(St, Cond, Assumption, isFeasible);
- }
-
- const GRState* Assume(const GRState* St, Loc Cond, bool Assumption,
- bool& isFeasible) {
- return StateMgr.Assume(St, Cond, Assumption, isFeasible);
- }
-
- const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
- bool Assumption, bool& isFeasible) {
- return StateMgr.AssumeInBound(St, Idx, UpperBound, Assumption, isFeasible);
- }
+ }
public:
NodeTy* MakeNode(NodeSet& Dst, Stmt* S, NodeTy* Pred, const GRState* St,
diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h
index 25863ffd4a..5c151efc34 100644
--- a/include/clang/Analysis/PathSensitive/GRState.h
+++ b/include/clang/Analysis/PathSensitive/GRState.h
@@ -158,6 +158,49 @@ public:
BasicValueFactory &getBasicVals() const;
SymbolManager &getSymbolManager() const;
+ GRTransferFuncs &getTransferFuncs() const;
+
+ //==---------------------------------------------------------------------==//
+ // Constraints on values.
+ //==---------------------------------------------------------------------==//
+ //
+ // Each GRState records constraints on symbolic values. These constraints
+ // are managed using the ConstraintManager associated with a GRStateManager.
+ // As constraints gradually accrue on symbolic values, added constraints
+ // may conflict and indicate that a state is infeasible (as no real values
+ // could satisfy all the constraints). This is the principal mechanism
+ // for modeling path-sensitivity in GRExprEngine/GRState.
+ //
+ // Various "Assume" methods form the interface for adding constraints to
+ // symbolic values. A call to "Assume" indicates an assumption being placed
+ // on one or symbolic values. Assume methods take the following inputs:
+ //
+ // (1) A GRState object representing the current state.
+ //
+ // (2) The assumed constraint (which is specific to a given "Assume" method).
+ //
+ // (3) A binary value "Assumption" that indicates whether the constraint is
+ // assumed to be true or false.
+ //
+ // The output of "Assume" are two values:
+ //
+ // (a) "isFeasible" is set to true or false to indicate whether or not
+ // the assumption is feasible.
+ //
+ // (b) A new GRState object with the added constraints.
+ //
+ // FIXME: (a) should probably disappear since it is redundant with (b).
+ // (i.e., (b) could just be set to NULL).
+ //
+
+ const GRState *assume(SVal condition, bool assumption) const;
+
+ const GRState *assumeInBound(SVal idx, SVal upperBound,
+ bool assumption) const;
+
+ //==---------------------------------------------------------------------==//
+ // Binding and retrieving values to/from the environment and symbolic store.
+ //==---------------------------------------------------------------------==//
const GRState *bindExpr(Stmt* Ex, SVal V, bool isBlkExpr,
bool Invalidate) const;
@@ -171,6 +214,8 @@ public:
const GRState *unbindLoc(Loc LV) const;
SVal getLValue(const VarDecl* VD) const;
+
+ const llvm::APSInt *getSymVal(SymbolRef sym) const;
SVal getSVal(Expr* Ex) const;
@@ -188,7 +233,10 @@ public:
template <typename CB> CB scanReachableSymbols(SVal val) const;
- // Trait based GDM dispatch.
+ //==---------------------------------------------------------------------==//
+ // Accessing the Generic Data Map (GDM).
+ //==---------------------------------------------------------------------==//
+
void* const* FindGDM(void* K) const;
template<typename T>
@@ -671,56 +719,6 @@ public:
return GRStateTrait<T>::MakeContext(p);
}
-
- //==---------------------------------------------------------------------==//
- // Constraints on values.
- //==---------------------------------------------------------------------==//
- //
- // Each GRState records constraints on symbolic values. These constraints
- // are managed using the ConstraintManager associated with a GRStateManager.
- // As constraints gradually accrue on symbolic values, added constraints
- // may conflict and indicate that a state is infeasible (as no real values
- // could satisfy all the constraints). This is the principal mechanism
- // for modeling path-sensitivity in GRExprEngine/GRState.
- //
- // Various "Assume" methods form the interface for adding constraints to
- // symbolic values. A call to "Assume" indicates an assumption being placed
- // on one or symbolic values. Assume methods take the following inputs:
- //
- // (1) A GRState object representing the current state.
- //
- // (2) The assumed constraint (which is specific to a given "Assume" method).
- //
- // (3) A binary value "Assumption" that indicates whether the constraint is
- // assumed to be true or false.
- //
- // The output of "Assume" are two values:
- //
- // (a) "isFeasible" is set to true or false to indicate whether or not
- // the assumption is feasible.
- //
- // (b) A new GRState object with the added constraints.
- //
- // FIXME: (a) should probably disappear since it is redundant with (b).
- // (i.e., (b) could just be set to NULL).
- //
-
- const GRState* Assume(const GRState* St, SVal Cond, bool Assumption,
- bool& isFeasible) {
- const GRState *state =
- ConstraintMgr->Assume(St, Cond, Assumption, isFeasible);
- assert(!isFeasible || state);
- return isFeasible ? state : NULL;
- }
-
- const GRState* AssumeInBound(const GRState* St, SVal Idx, SVal UpperBound,
- bool Assumption, bool& isFeasible) {
- const GRState *state =
- ConstraintMgr->AssumeInBound(St, Idx, UpperBound, Assumption,
- isFeasible);
- assert(!isFeasible || state);
- return isFeasible ? state : NULL;
- }
const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) {
return ConstraintMgr->getSymVal(St, sym);
@@ -736,6 +734,15 @@ public:
// Out-of-line method definitions for GRState.
//===----------------------------------------------------------------------===//
+inline const GRState *GRState::assume(SVal Cond, bool Assumption) const {
+ return Mgr->ConstraintMgr->Assume(this, Cond, Assumption);
+}
+
+inline const GRState *GRState::assumeInBound(SVal Idx, SVal UpperBound,
+ bool Assumption) const {
+ return Mgr->ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption);
+}
+
inline const GRState *GRState::bindExpr(Stmt* Ex, SVal V, bool isBlkExpr,
bool Invalidate) const {
return Mgr->BindExpr(this, Ex, V, isBlkExpr, Invalidate);
@@ -758,6 +765,10 @@ inline SVal GRState::getLValue(const VarDecl* VD) const {
return Mgr->GetLValue(this, VD);
}
+inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
+ return Mgr->getSymVal(this, sym);
+}
+
inline SVal GRState::getSVal(Expr* Ex) const {
return Mgr->GetSVal(this, Ex);
}
@@ -782,13 +793,17 @@ inline SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
return Mgr->GetSValAsScalarOrLoc(this, R);
}
-inline BasicValueFactory& GRState::getBasicVals() const {
+inline BasicValueFactory &GRState::getBasicVals() const {
return Mgr->getBasicVals();
}
-inline SymbolManager& GRState::getSymbolManager() const {
+inline SymbolManager &GRState::getSymbolManager() const {
return Mgr->getSymbolManager();
}
+
+inline GRTransferFuncs &GRState::getTransferFuncs() const {
+ return Mgr->getTransferFuncs();
+}
template<typename T>
const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
index 0f353d0700..c2f8f5aae0 100644
--- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
@@ -110,11 +110,9 @@ public:
// Assumptions.
- virtual const GRState* EvalAssume(GRStateManager& VMgr,
- const GRState* St,
- SVal Cond, bool Assumption,
- bool& isFeasible) {
- return St;
+ virtual const GRState* EvalAssume(const GRState *state,
+ SVal Cond, bool Assumption) {
+ return state;
}
};
diff --git a/lib/Analysis/BasicConstraintManager.cpp b/lib/Analysis/BasicConstraintManager.cpp
index 1f907baa24..7bd22fd313 100644
--- a/lib/Analysis/BasicConstraintManager.cpp
+++ b/lib/Analysis/BasicConstraintManager.cpp
@@ -53,37 +53,37 @@ public:
BasicConstraintManager(GRStateManager& statemgr)
: SimpleConstraintManager(statemgr), ISetFactory(statemgr.getAllocator()) {}
- const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible);
+ const GRState* AssumeSymNE(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& V);
- const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible);
+ const GRState* AssumeSymEQ(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& V);
- const GRState* AssumeSymLT(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible);
+ const GRState* AssumeSymLT(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& V);
- const GRState* AssumeSymGT(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible);
+ const GRState* AssumeSymGT(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& V);
- const GRState* AssumeSymGE(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible);
+ const GRState* AssumeSymGE(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& V);
- const GRState* AssumeSymLE(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible);
+ const GRState* AssumeSymLE(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& V);
- const GRState* AddEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
+ const GRState* AddEQ(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
- const GRState* AddNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V);
+ const GRState* AddNE(const GRState* state, SymbolRef sym, const llvm::APSInt& V);
- const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) const;
- bool isNotEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V)
+ const llvm::APSInt* getSymVal(const GRState* state, SymbolRef sym) const;
+ bool isNotEqual(const GRState* state, SymbolRef sym, const llvm::APSInt& V)
const;
- bool isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V)
+ bool isEqual(const GRState* state, SymbolRef sym, const llvm::APSInt& V)
const;
- const GRState* RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper);
+ const GRState* RemoveDeadBindings(const GRState* state, SymbolReaper& SymReaper);
- void print(const GRState* St, std::ostream& Out,
+ void print(const GRState* state, std::ostream& Out,
const char* nl, const char *sep);
};
@@ -95,87 +95,77 @@ ConstraintManager* clang::CreateBasicConstraintManager(GRStateManager& StateMgr)
}
const GRState*
-BasicConstraintManager::AssumeSymNE(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible) {
+BasicConstraintManager::AssumeSymNE(const GRState *state, SymbolRef sym,
+ const llvm::APSInt& V) {
// First, determine if sym == X, where X != V.
- if (const llvm::APSInt* X = getSymVal(St, sym)) {
- isFeasible = (*X != V);
- return St;
+ if (const llvm::APSInt* X = getSymVal(state, sym)) {
+ bool isFeasible = (*X != V);
+ return isFeasible ? state : NULL;
}
// Second, determine if sym != V.
- if (isNotEqual(St, sym, V)) {
- isFeasible = true;
- return St;
- }
+ if (isNotEqual(state, sym, V))
+ return state;
// If we reach here, sym is not a constant and we don't know if it is != V.
// Make that assumption.
- isFeasible = true;
- return AddNE(St, sym, V);
+ return AddNE(state, sym, V);
}
-const GRState*
-BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible) {
+const GRState *BasicConstraintManager::AssumeSymEQ(const GRState *state,
+ SymbolRef sym,
+ const llvm::APSInt &V) {
// First, determine if sym == X, where X != V.
- if (const llvm::APSInt* X = getSymVal(St, sym)) {
- isFeasible = *X == V;
- return St;
+ if (const llvm::APSInt* X = getSymVal(state, sym)) {
+ bool isFeasible = *X == V;
+ return isFeasible ? state : NULL;
}
// Second, determine if sym != V.
- if (isNotEqual(St, sym, V)) {
- isFeasible = false;
- return St;
- }
+ if (isNotEqual(state, sym, V))
+ return NULL;
// If we reach here, sym is not a constant and we don't know if it is == V.
// Make that assumption.
-
- isFeasible = true;
- return AddEQ(St, sym, V);
+ return AddEQ(state, sym, V);
}
// These logic will be handled in another ConstraintManager.
-const GRState*
-BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible) {
-
+const GRState *BasicConstraintManager::AssumeSymLT(const GRState *state,
+ SymbolRef sym,
+ const llvm::APSInt& V) {
// Is 'V' the smallest possible value?
if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
// sym cannot be any value less than 'V'. This path is infeasible.
- isFeasible = false;
- return St;
+ return NULL;
}
// FIXME: For now have assuming x < y be the same as assuming sym != V;
- return AssumeSymNE(St, sym, V, isFeasible);
+ return AssumeSymNE(state, sym, V);
}
-const GRState*
-BasicConstraintManager::AssumeSymGT(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible) {
+const GRState *BasicConstraintManager::AssumeSymGT(const GRState *state,
+ SymbolRef sym,
+ const llvm::APSInt& V) {
// Is 'V' the largest possible value?
if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
// sym cannot be any value greater than 'V'. This path is infeasible.
- isFeasible = false;
- return St;
+ return NULL;
}
// FIXME: For now have assuming x > y be the same as assuming sym != V;
- return AssumeSymNE(St, sym, V, isFeasible);
+ return AssumeSymNE(state, sym, V);
}
-const GRState*
-BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible) {
+const GRState *BasicConstraintManager::AssumeSymGE(const GRState *state,
+ SymbolRef sym,
+ const llvm::APSInt &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;
+ if (const llvm::APSInt *X = getSymVal(state, sym)) {
+ bool isFeasible = *X >= V;
+ return isFeasible ? state : NULL;
}
// Sym is not a constant, but it is worth looking to see if V is the
@@ -183,28 +173,25 @@ BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
// If we know that sym != V, then this condition is infeasible since
// there is no other value greater than V.
- isFeasible = !isNotEqual(St, sym, V);
+ bool isFeasible = !isNotEqual(state, sym, V);
// If the path is still feasible then as a consequence we know that
// 'sym == V' because we cannot have 'sym > V' (no larger values).
// Add this constraint.
- if (isFeasible)
- return AddEQ(St, sym, V);
+ return isFeasible ? AddEQ(state, sym, V) : NULL;
}
- else
- isFeasible = true;
- return St;
+ return state;
}
const GRState*
-BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
- const llvm::APSInt& V, bool& isFeasible) {
+BasicConstraintManager::AssumeSymLE(const GRState* state, SymbolRef sym,
+ const llvm::APSInt& 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;
+ if (const llvm::APSInt* X = getSymVal(state, sym)) {
+ bool isFeasible = *X <= V;
+ return isFeasible ? state : NULL;
}
// Sym is not a constant, but it is worth looking to see if V is the
@@ -212,18 +199,15 @@ BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
// 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);
+ bool isFeasible = !isNotEqual(state, 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);
+ return isFeasible ? AddEQ(state, sym, V) : NULL;
}
- else
- isFeasible = true;
- return St;
+ return state;
}
const GRState* BasicConstraintManager::AddEQ(const GRState* state, SymbolRef sym,
@@ -246,26 +230,26 @@ const GRState* BasicConstraintManager::AddNE(const GRState* state, SymbolRef sym
return state->set<ConstNotEq>(sym, S);
}
-const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St,
+const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* state,
SymbolRef sym) const {
- const ConstEqTy::data_type* T = St->get<ConstEq>(sym);
+ const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
return T ? *T : NULL;
}
-bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym,
+bool BasicConstraintManager::isNotEqual(const GRState* state, SymbolRef sym,
const llvm::APSInt& V) const {
// Retrieve the NE-set associated with the given symbol.
- const ConstNotEqTy::data_type* T = St->get<ConstNotEq>(sym);
+ const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
// See if V is present in the NE-set.
return T ? T->contains(&V) : false;
}
-bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym,
+bool BasicConstraintManager::isEqual(const GRState* state, SymbolRef sym,
const llvm::APSInt& V) const {
// Retrieve the EQ-set associated with the given symbol.
- const ConstEqTy::data_type* T = St->get<ConstEq>(sym);
+ const ConstEqTy::data_type* T = state->get<ConstEq>(sym);
// See if V is present in the EQ-set.
return T ? **T == V : false;
}
@@ -296,11 +280,11 @@ BasicConstraintManager::RemoveDeadBindings(const GRState* state,
return state->set<ConstNotEq>(CNE);
}
-void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
+void BasicConstraintManager::print(const GRState* state, std::ostream& Out,
const char* nl, const char *sep) {
// Print equality constraints.
- ConstEqTy CE = St->get<ConstEq>();
+ ConstEqTy CE = state->get<ConstEq>();
if (!CE.isEmpty()) {
Out << nl << sep << "'==' constraints:";
@@ -314,7 +298,7 @@ void BasicConstraintManager::print(const GRState* St, std::ostream& Out,
// Print != constraints.
- ConstNotEqTy CNE = St->get<ConstNotEq>();
+ ConstNotEqTy CNE = state->get<ConstNotEq>();
if (!CNE.isEmpty()) {
Out << nl << sep << "'!=' constraints:";
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 6603ba72b7..9cdc769431 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1953,9 +1953,8 @@ public:
// Assumptions.
- virtual const GRState* EvalAssume(GRStateManager& VMgr,
- const GRState* St, SVal Cond,
- bool Assumption, bool& isFeasible);
+ virtual const GRState *EvalAssume(const GRState* state, SVal condition,
+ bool assumption);
};
} // end anonymous namespace
@@ -3307,10 +3306,8 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
// Assumptions.
-const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
- const GRState* state,
- SVal Cond, bool Assumption,
- bool& isFeasible) {
+const GRState* CFRefCount::EvalAssume(const GRState *state,
+ SVal Cond, bool Assumption) {
// FIXME: We may add to the interface of EvalAssume the list of symbols
// whose assumptions have changed. For now we just iterate through the
@@ -3329,7 +3326,7 @@ const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
// Check if the symbol is null (or equal to any constant).
// If this is the case, stop tracking the symbol.
- if (VMgr.getSymVal(state, I.getKey())) {
+ if (state->getSymVal(I.getKey())) {
changed = true;
B = RefBFactory.Remove(B, I.getKey());
}
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index e392de6aab..c43c83b259 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -181,10 +181,9 @@ const GRState* GRExprEngine::getInitialState() {
SVal Constraint = EvalBinOp(state, BinaryOperator::GT, V,
ValMgr.makeZeroVal(T),
getContext().IntTy);
- bool isFeasible = false;
- const GRState *newState = Assume(state, Constraint, true,
- isFeasible);
- if (newState) state = newState;
+
+ if (const GRState *newState = state->assume(Constraint, true))
+ state = newState;
}
}
@@ -708,21 +707,13 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
}
// Process the true branch.
-
- bool isFeasible = false;
- const GRState* state = Assume(PrevState, V, true, isFeasible);
-
- if (isFeasible)
+ if (const GRState *state = PrevState->assume(V, true))
builder.generateNode(MarkBranch(state, Term, true), true);
else
builder.markInfeasible(true);
// Process the false branch.
-
- isFeasible = false;
- state = Assume(PrevState, V, false, isFeasible);
-
- if (isFeasible)
+ if (const GRState *state = PrevState->assume(V, false))
builder.generateNode(MarkBranch(state, Term, false), false);
else
builder.markInfeasible(false);
@@ -808,7 +799,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
}
const GRState* DefaultSt = state;
- bool DefaultFeasible = false;
+ bool defaultIsFeasible = false;
for (iterator I = builder.begin(), EI = builder.end(); I != EI; ++I) {
CaseStmt* Case = cast<CaseStmt>(I.getCase());
@@ -846,11 +837,8 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
getContext().IntTy);
// Now "assume" that the case matches.
- bool isFeasible = false;
- const GRState* StNew = Assume(state, Res, true, isFeasible);
-
- if (isFeasible) {
- builder.generateCaseStmtNode(I, StNew);
+ if (const GRState* stateNew = state->assume(Res, true)) {
+ builder.generateCaseStmtNode(I, stateNew);
// If CondV evaluates to a constant, then we know that this
// is the *only* case that we can take, so stop evaluating the
@@ -861,13 +849,9 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
// Now "assume" that the case doesn't match. Add this state
// to the default state (if it is feasible).
-
- isFeasible = false;
- StNew = Assume(DefaultSt, Res, false, isFeasible);
-
- if (isFeasible) {
- DefaultFeasible = true;
- DefaultSt = StNew;
+ if (const GRState *stateNew = DefaultSt->assume(Res, false)) {
+ defaultIsFeasible = true;
+ DefaultSt = stateNew;
}
// Concretize the next value in the range.
@@ -882,7 +866,7 @@ void GRExprEngine::ProcessSwitch(SwitchNodeBuilder& builder) {
// If we reach here, than we know that the default branch is
// possible.
- if (DefaultFeasible) builder.generateDefaultCaseNode(DefaultSt);
+ if (defaultIsFeasible) builder.generateDefaultCaseNode(DefaultSt);
}
//===----------------------------------------------------------------------===//
@@ -922,27 +906,17 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred,
// or 1. Alternatively, we could take a lazy approach, and calculate this
// value later when necessary. We don't have the machinery in place for
// this right now, and since most logical expressions are used for branches,
- // the payoff is not likely to be large. Instead, we do eager evaluation.
-
- bool isFeasible = false;
- const GRState* NewState = Assume(state, X, true, isFeasible);
-
- if (isFeasible)
- MakeNode(Dst, B, Pred,
- BindBlkExpr(NewState, B, MakeConstantVal(1U, B)));
+ // the payoff is not likely to be large. Instead, we do eager evaluation.
+ if (const GRState *newState = state->assume(X, true))
+ MakeNode(Dst, B, Pred, BindBlkExpr(newState, B, MakeConstantVal(1U, B)));
- isFeasible = false;
- NewState = Assume(state, X, false, isFeasible);
-
- if (isFeasible)
- MakeNode(Dst, B, Pred,
- BindBlkExpr(NewState, B, MakeConstantVal(0U, B)));
+ if (const GRState *newState = state->assume(X, false))
+ MakeNode(Dst, B, Pred, BindBlkExpr(newState, B, MakeConstantVal(0U, B)));
}
else {
// We took the LHS expression. Depending on whether we are '&&' or
// '||' we know what the value of the expression is via properties of
// the short-circuiting.
-
X = MakeConstantVal( B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, B);
MakeNode(Dst, B, Pred, BindBlkExpr(state, B, X));
}
@@ -1189,15 +1163,12 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
Loc LV = cast<Loc>(location);
// "Assume" that the pointer is not NULL.
- bool isFeasibleNotNull = false;
- const GRState* StNotNull = Assume(state, LV, true, isFeasibleNotNull);
+ const GRState *StNotNull = state->assume(LV, true);
// "Assume" that the pointer is NULL.
- bool isFeasibleNull = false;
- const GRState *StNull = Assume(state, LV, false, isFeasibleNull);
+ const GRState *StNull = state->assume(LV, false);
- if (isFeasibleNull) {
-
+ if (StNull) {
// Use the Generic Data Map to mark in the state what lval was null.
const SVal* PersistentLV = getBasicVals().getPersistentSVal(LV);
StNull = StNull->set<GRState::NullDerefTag>(PersistentLV);
@@ -1208,17 +1179,15 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
Builder->generateNode(Ex, StNull, Pred,
ProgramPoint::PostNullCheckFailedKind);
- if (NullNode) {
-
- NullNode->markAsSink();
-
- if (isFeasibleNotNull) ImplicitNullDeref.insert(NullNode);
+ if (NullNode) {
+ NullNode->markAsSink();
+ if (StNotNull) ImplicitNullDeref.insert(NullNode);
else ExplicitNullDeref.insert(NullNode);
}
}
- if (!isFeasibleNotNull)
- return 0;
+ if (!StNotNull)
+ return NULL;
// Check for out-of-bound array access.
if (isa<loc::MemRegionVal>(LV)) {
@@ -1230,15 +1199,12 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
SVal NumElements = getStoreManager().getSizeInElements(StNotNull,
ER->getSuperRegion());
- bool isFeasibleInBound = false;
- const GRState* StInBound = AssumeInBound(StNotNull, Idx, NumElements,
- true, isFeasibleInBound);
+ const GRState * StInBound = StNotNull->assumeInBound(Idx, NumElements,
+ true);
+ const GRState* StOutBound = StNotNull->assumeInBound(Idx, NumElements,
+ false);
- bool isFeasibleOutBound = false;
- const GRState* StOutBound = AssumeInBound(StNotNull, Idx, NumElements,
- false, isFeasibleOutBound);
-
- if (isFeasibleOutBound) {
+ if (StOutBound) {
// Report warning. Make sink node manually.
NodeTy* OOBNode =
Builder->generateNode(Ex, StOutBound, Pred,
@@ -1247,16 +1213,16 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
if (OOBNode) {
OOBNode->markAsSink();
- if (isFeasibleInBound)
+ if (StInBound)
ImplicitOOBMemAccesses.insert(OOBNode);
else
ExplicitOOBMemAccesses.insert(OOBNode);
}
}
- if (!isFeasibleInBound)
- return 0;
-
+ if (!StInBound)
+ return NULL;
+
StNotNull = StInBound;
}
}
@@ -1329,19 +1295,18 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
ExplodedNode<GRState> *N = *I;
const GRState *stateLoad = N->getState();
- SVal theValueVal = StateMgr.GetSVal(stateLoad, theValueExpr);
- SVal oldValueVal = StateMgr.GetSVal(stateLoad, oldValueExpr);
+ SVal theValueVal = stateLoad->getSVal(theValueExpr);
+ SVal oldValueVal = stateLoad->getSVal(oldValueExpr);
// Perform the comparison.
SVal Cmp = Engine.EvalBinOp(stateLoad,
BinaryOperator::EQ, theValueVal, oldValueVal,
Engine.getContext().IntTy);
- bool isFeasible = false;
- const GRState *stateEqual = StateMgr.Assume(stateLoad, Cmp, true,
- isFeasible);
+
+ const GRState *stateEqual = stateLoad->assume(Cmp, true);
// Were they equal?
- if (isFeasible) {
+ if (stateEqual) {
// Perform the store.
ExplodedNodeSet<GRState> TmpStore;
Engine.EvalStore(TmpStore, theValueExpr, N, stateEqual, location,
@@ -1359,11 +1324,7 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet<GRState>& Dst,
}
// Were they not equal?
- isFeasible = false;
- const GRState *stateNotEqual = StateMgr.Assume(stateLoad, Cmp, false,
- isFeasible);
-
- if (isFeasible) {
+ if (const GRState *stateNotEqual = stateLoad->assume(Cmp, false)) {
SVal Res = Engine.getValueManager().makeTruthVal(false, CE->getType());
Engine.MakeNode(Dst, CE, N, Engine.BindExpr(stateNotEqual, CE, Res));
}
@@ -1659,19 +1620,15 @@ void GRExprEngine::EvalEagerlyAssume(NodeSet &Dst, NodeSet &Src, Expr *Ex) {
SVal V = GetSVal(state, Ex);
if (isa<nonloc::SymExpr