From: Ted Kremenek Date: Sun, 17 Aug 2008 03:20:02 +0000 (+0000) Subject: Migrate the retain/release checker to not manage the RefBindings::Factory object X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9d17f9384651d1052a17978d2e160448bfad404;p=clang Migrate the retain/release checker to not manage the RefBindings::Factory object directly, but instead have GRStateManager manage it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54862 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 9670f61e22..39d79bc3ae 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -566,6 +566,11 @@ public: return GRStateRef(Mgr->remove(St, K, C), *Mgr); } + template + GRStateRef remove(typename GRStateTrait::key_type K) { + return GRStateRef(Mgr->remove(St, K, get_context()), *Mgr); + } + // Pretty-printing. void print(std::ostream& Out, const char* nl = "\n", const char *sep = "") const; diff --git a/include/clang/Analysis/PathSensitive/GRStateTrait.h b/include/clang/Analysis/PathSensitive/GRStateTrait.h index 33c03227a0..9409aafaa5 100644 --- a/include/clang/Analysis/PathSensitive/GRStateTrait.h +++ b/include/clang/Analysis/PathSensitive/GRStateTrait.h @@ -54,11 +54,11 @@ namespace clang { return *((typename data_type::Factory*) p); } - static inline void* CreateContext(llvm::BumpPtrAllocator& Alloc) { + static void* CreateContext(llvm::BumpPtrAllocator& Alloc) { return new typename data_type::Factory(Alloc); } - static inline void DeleteContext(void* Ctx) { + static void DeleteContext(void* Ctx) { delete (typename data_type::Factory*) Ctx; } }; diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 2fdd0290e1..16ce58f4ca 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" #include "clang/Analysis/PathSensitive/GRState.h" +#include "clang/Analysis/PathSensitive/GRStateTrait.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/LocalCheckers.h" #include "clang/Analysis/PathDiagnostic.h" @@ -1199,40 +1200,14 @@ void RefVal::print(std::ostream& Out) const { //===----------------------------------------------------------------------===// typedef llvm::ImmutableMap RefBindings; -typedef RefBindings::Factory RefBFactoryTy; - static int RefBIndex = 0; namespace clang { -template<> struct GRStateTrait { - typedef RefBindings data_type; - typedef RefBFactoryTy& context_type; - typedef SymbolID key_type; - typedef RefVal value_type; - typedef const RefVal* lookup_type; - - static RefBindings MakeData(void* const* p) { - return p ? RefBindings((RefBindings::TreeTy*) *p) : RefBindings(0); - } - static void* MakeVoidPtr(RefBindings B) { - return B.getRoot(); - } - static void* GDMIndex() { - return &RefBIndex; - } - static lookup_type Lookup(RefBindings B, SymbolID K) { - return B.lookup(K); - } - static data_type Set(RefBindings B, key_type K, value_type E, - RefBFactoryTy& F) { - return F.Add(B, K, E); - } - - static data_type Remove(RefBindings B, SymbolID K, RefBFactoryTy& F) { - return F.Remove(B, K); - } -}; -} + template<> + struct GRStateTrait : public GRStatePartialTrait { + static inline void* GDMIndex() { return &RefBIndex; } + }; +} //===----------------------------------------------------------------------===// // Transfer functions. @@ -1260,19 +1235,20 @@ public: private: RetainSummaryManager Summaries; const LangOptions& LOpts; - RefBFactoryTy RefBFactory; + UseAfterReleasesTy UseAfterReleases; ReleasesNotOwnedTy ReleasesNotOwned; LeaksTy Leaks; RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E, - RefVal::Kind& hasErr); + RefVal::Kind& hasErr, RefBindings::Factory& RefBFactory); RefVal::Kind& Update(GRStateRef& state, SymbolID sym, RefVal V, ArgEffect E, RefVal::Kind& hasErr) { state = state.set(Update(state.get(), sym, V, - E, hasErr)); + E, hasErr, + state.get_context())); return hasErr; } @@ -1534,7 +1510,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, if (isa(X)) { SymbolID Sym = cast(X).getSymbol(); - state = state.remove(Sym, RefBFactory); + state = state.remove(Sym); } // Set the value of the variable to be a conjured symbol. @@ -1624,7 +1600,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count); QualType RetT = GetReturnType(Ex, Eng.getContext()); - state = state.set(Sym, RefVal::makeOwned(RetT), RefBFactory); + state = state.set(Sym, RefVal::makeOwned(RetT)); state = state.SetRVal(Ex, lval::SymbolVal(Sym), false); #if 0 @@ -1644,7 +1620,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count); QualType RetT = GetReturnType(Ex, Eng.getContext()); - state = state.set(Sym, RefVal::makeNotOwned(RetT), RefBFactory); + state = state.set(Sym, RefVal::makeNotOwned(RetT)); state = state.SetRVal(Ex, lval::SymbolVal(Sym), false); break; } @@ -1747,7 +1723,7 @@ void CFRefCount::EvalStore(ExplodedNodeSet& Dst, return; // Nuke the binding. - state = state.remove(Sym, RefBFactory); + state = state.remove(Sym); // Hand of the remaining logic to the parent implementation. GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, state, TargetLV, Val); @@ -1765,9 +1741,9 @@ const GRState* CFRefCount::HandleSymbolDeath(GRStateManager& VMgr, GRStateRef state(St, VMgr); if (!hasLeak) - return state.remove(sid, RefBFactory); + return state.remove(sid); - return state.set(sid, V ^ RefVal::ErrorLeak, RefBFactory); + return state.set(sid, V ^ RefVal::ErrorLeak); } void CFRefCount::EvalEndPath(GRExprEngine& Eng, @@ -1899,7 +1875,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet& Dst, } // Update the binding. - state = state.set(Sym, X, RefBFactory); + state = state.set(Sym, X); Builder.MakeNode(Dst, S, Pred, state); } @@ -1922,6 +1898,9 @@ const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr, return St; bool changed = false; + + GRStateRef state(St, VMgr); + RefBindings::Factory& RefBFactory = state.get_context(); for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) { // Check if the symbol is null (or equal to any constant). @@ -1932,17 +1911,16 @@ const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr, } } - if (!changed) - return St; + if (changed) + state = state.set(B); - GRStateRef state(St, VMgr); - state = state.set(B); return state; } RefBindings CFRefCount::Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E, - RefVal::Kind& hasErr) { + RefVal::Kind& hasErr, + RefBindings::Factory& RefBFactory) { // FIXME: This dispatch can potentially be sped up by unifiying it into // a single switch statement. Opt for simplicity for now.