diff options
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/GRState.h | 40 | ||||
-rw-r--r-- | clang/lib/Analysis/CFRefCount.cpp | 17 |
2 files changed, 47 insertions, 10 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h index ae5423111fc..c9424c92310 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRState.h +++ b/clang/include/clang/Analysis/PathSensitive/GRState.h @@ -158,6 +158,10 @@ public: BasicValueFactory &getBasicVals() const; SymbolManager &getSymbolManager() const; + + const GRState *bind(Loc location, SVal V) const; + + const GRState *bind(SVal location, SVal V) const; SVal getLValue(const VarDecl* VD) const; @@ -173,6 +177,8 @@ public: SVal getSValAsScalarOrLoc(const MemRegion *R) const; + template <typename CB> CB scanReachableSymbols(SVal val) const; + // Trait based GDM dispatch. void* const* FindGDM(void* K) const; @@ -195,6 +201,14 @@ public: template <typename T> typename GRStateTrait<T>::context_type get_context() const; + + template<typename T> + const GRState *remove(typename GRStateTrait<T>::key_type K) const; + + template<typename T> + const GRState *remove(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::context_type C) const; + template<typename T> const GRState *set(typename GRStateTrait<T>::data_type D) const; @@ -717,6 +731,14 @@ public: // Out-of-line method definitions for GRState. //===----------------------------------------------------------------------===// +inline const GRState *GRState::bind(Loc LV, SVal V) const { + return Mgr->BindLoc(this, LV, V); +} + +inline const GRState *GRState::bind(SVal LV, SVal V) const { + return !isa<Loc>(LV) ? this : bind(cast<Loc>(LV), V); +} + inline SVal GRState::getLValue(const VarDecl* VD) const { return Mgr->GetLValue(this, VD); } @@ -764,6 +786,17 @@ typename GRStateTrait<T>::context_type GRState::get_context() const { } template<typename T> +const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const { + return Mgr->remove<T>(this, K, get_context<T>()); +} + +template<typename T> +const GRState *GRState::remove(typename GRStateTrait<T>::key_type K, + typename GRStateTrait<T>::context_type C) const { + return Mgr->remove<T>(this, K, C); +} + +template<typename T> const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const { return Mgr->set<T>(this, D); } @@ -780,6 +813,13 @@ const GRState *GRState::set(typename GRStateTrait<T>::key_type K, typename GRStateTrait<T>::context_type C) const { return Mgr->set<T>(this, K, E, C); } + +template <typename CB> +CB GRState::scanReachableSymbols(SVal val) const { + CB cb(this); + Mgr->scanReachableSymbols(val, this, cb); + return cb; +} //===----------------------------------------------------------------------===// // GRStateRef - A "fat" reference to GRState that also bundles GRStateManager. diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index d1f6bc8b310..94fb9f6bb5b 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -3114,17 +3114,15 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst, namespace { class VISIBILITY_HIDDEN StopTrackingCallback : public SymbolVisitor { - GRStateRef state; + const GRState *state; public: - StopTrackingCallback(GRStateRef st) : state(st) {} - GRStateRef getState() { return state; } + StopTrackingCallback(const GRState *st) : state(st) {} + const GRState *getState() const { return state; } bool VisitSymbol(SymbolRef sym) { - state = state.remove<RefBindings>(sym); + state = state->remove<RefBindings>(sym); return true; } - - const GRState* getState() const { return state.getState(); } }; } // end anonymous namespace @@ -3139,7 +3137,7 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) { // (2) we are binding to a memregion that does not have stack storage // (3) we are binding to a memregion with stack storage that the store // does not understand. - GRStateRef state = B.getState(); + const GRState *state = B.getState(); if (!isa<loc::MemRegionVal>(location)) escapes = true; @@ -3151,7 +3149,7 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) { // To test (3), generate a new state with the binding removed. If it is // the same state, then it escapes (since the store cannot represent // the binding). - escapes = (state == (state.BindLoc(cast<Loc>(location), UnknownVal()))); + escapes = (state == (state->bind(cast<Loc>(location), UnknownVal()))); } } @@ -3163,10 +3161,9 @@ void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) { // Otherwise, find all symbols referenced by 'val' that we are tracking // and stop tracking them. - B.MakeNode(state.scanReachableSymbols<StopTrackingCallback>(val).getState()); + B.MakeNode(state->scanReachableSymbols<StopTrackingCallback>(val).getState()); } - // Return statements. void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst, |