diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h index ae5423111fcd..c9424c923103 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 CB scanReachableSymbols(SVal val) const; + // Trait based GDM dispatch. void* const* FindGDM(void* K) const; @@ -195,6 +201,14 @@ public: template typename GRStateTrait::context_type get_context() const; + + template + const GRState *remove(typename GRStateTrait::key_type K) const; + + template + const GRState *remove(typename GRStateTrait::key_type K, + typename GRStateTrait::context_type C) const; + template const GRState *set(typename GRStateTrait::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(LV) ? this : bind(cast(LV), V); +} + inline SVal GRState::getLValue(const VarDecl* VD) const { return Mgr->GetLValue(this, VD); } @@ -763,6 +785,17 @@ typename GRStateTrait::context_type GRState::get_context() const { return Mgr->get_context(); } +template +const GRState *GRState::remove(typename GRStateTrait::key_type K) const { + return Mgr->remove(this, K, get_context()); +} + +template +const GRState *GRState::remove(typename GRStateTrait::key_type K, + typename GRStateTrait::context_type C) const { + return Mgr->remove(this, K, C); +} + template const GRState *GRState::set(typename GRStateTrait::data_type D) const { return Mgr->set(this, D); @@ -780,6 +813,13 @@ const GRState *GRState::set(typename GRStateTrait::key_type K, typename GRStateTrait::context_type C) const { return Mgr->set(this, K, E, C); } + +template +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 d1f6bc8b3107..94fb9f6bb5b6 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -3114,17 +3114,15 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& 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(sym); + state = state->remove(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(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(location), UnknownVal()))); + escapes = (state == (state->bind(cast(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(val).getState()); + B.MakeNode(state->scanReachableSymbols(val).getState()); } - // Return statements. void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,