diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/ConstraintManager.h | 21 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 19 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRState.h | 121 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRTransferFuncs.h | 8 | ||||
-rw-r--r-- | lib/Analysis/BasicConstraintManager.cpp | 160 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 13 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 194 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 13 | ||||
-rw-r--r-- | lib/Analysis/RangeConstraintManager.cpp | 17 | ||||
-rw-r--r-- | lib/Analysis/SimpleConstraintManager.cpp | 183 | ||||
-rw-r--r-- | lib/Analysis/SimpleConstraintManager.h | 78 |
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 |