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
This commit is contained in:
Ted Kremenek 2008-08-17 03:20:02 +00:00
Родитель e96de3e913
Коммит b9d17f9384
3 изменённых файлов: 31 добавлений и 48 удалений

Просмотреть файл

@ -566,6 +566,11 @@ public:
return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr); return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr);
} }
template<typename T>
GRStateRef remove(typename GRStateTrait<T>::key_type K) {
return GRStateRef(Mgr->remove<T>(St, K, get_context<T>()), *Mgr);
}
// Pretty-printing. // Pretty-printing.
void print(std::ostream& Out, const char* nl = "\n", void print(std::ostream& Out, const char* nl = "\n",
const char *sep = "") const; const char *sep = "") const;

Просмотреть файл

@ -54,11 +54,11 @@ namespace clang {
return *((typename data_type::Factory*) p); 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); return new typename data_type::Factory(Alloc);
} }
static inline void DeleteContext(void* Ctx) { static void DeleteContext(void* Ctx) {
delete (typename data_type::Factory*) Ctx; delete (typename data_type::Factory*) Ctx;
} }
}; };

Просмотреть файл

@ -16,6 +16,7 @@
#include "clang/Basic/LangOptions.h" #include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManager.h"
#include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/PathSensitive/GRStateTrait.h"
#include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/LocalCheckers.h" #include "clang/Analysis/LocalCheckers.h"
#include "clang/Analysis/PathDiagnostic.h" #include "clang/Analysis/PathDiagnostic.h"
@ -1199,40 +1200,14 @@ void RefVal::print(std::ostream& Out) const {
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings; typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings;
typedef RefBindings::Factory RefBFactoryTy;
static int RefBIndex = 0; static int RefBIndex = 0;
namespace clang { namespace clang {
template<> struct GRStateTrait<RefBindings> { template<>
typedef RefBindings data_type; struct GRStateTrait<RefBindings> : public GRStatePartialTrait<RefBindings> {
typedef RefBFactoryTy& context_type; static inline void* GDMIndex() { return &RefBIndex; }
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);
}
};
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Transfer functions. // Transfer functions.
@ -1260,19 +1235,20 @@ public:
private: private:
RetainSummaryManager Summaries; RetainSummaryManager Summaries;
const LangOptions& LOpts; const LangOptions& LOpts;
RefBFactoryTy RefBFactory;
UseAfterReleasesTy UseAfterReleases; UseAfterReleasesTy UseAfterReleases;
ReleasesNotOwnedTy ReleasesNotOwned; ReleasesNotOwnedTy ReleasesNotOwned;
LeaksTy Leaks; LeaksTy Leaks;
RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E, 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, RefVal::Kind& Update(GRStateRef& state, SymbolID sym, RefVal V,
ArgEffect E, RefVal::Kind& hasErr) { ArgEffect E, RefVal::Kind& hasErr) {
state = state.set<RefBindings>(Update(state.get<RefBindings>(), sym, V, state = state.set<RefBindings>(Update(state.get<RefBindings>(), sym, V,
E, hasErr)); E, hasErr,
state.get_context<RefBindings>()));
return hasErr; return hasErr;
} }
@ -1534,7 +1510,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (isa<lval::SymbolVal>(X)) { if (isa<lval::SymbolVal>(X)) {
SymbolID Sym = cast<lval::SymbolVal>(X).getSymbol(); SymbolID Sym = cast<lval::SymbolVal>(X).getSymbol();
state = state.remove<RefBindings>(Sym, RefBFactory); state = state.remove<RefBindings>(Sym);
} }
// Set the value of the variable to be a conjured symbol. // Set the value of the variable to be a conjured symbol.
@ -1624,7 +1600,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count); SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
QualType RetT = GetReturnType(Ex, Eng.getContext()); QualType RetT = GetReturnType(Ex, Eng.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT), RefBFactory); state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT));
state = state.SetRVal(Ex, lval::SymbolVal(Sym), false); state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
#if 0 #if 0
@ -1644,7 +1620,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count); SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
QualType RetT = GetReturnType(Ex, Eng.getContext()); QualType RetT = GetReturnType(Ex, Eng.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT), RefBFactory); state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT));
state = state.SetRVal(Ex, lval::SymbolVal(Sym), false); state = state.SetRVal(Ex, lval::SymbolVal(Sym), false);
break; break;
} }
@ -1747,7 +1723,7 @@ void CFRefCount::EvalStore(ExplodedNodeSet<GRState>& Dst,
return; return;
// Nuke the binding. // Nuke the binding.
state = state.remove<RefBindings>(Sym, RefBFactory); state = state.remove<RefBindings>(Sym);
// Hand of the remaining logic to the parent implementation. // Hand of the remaining logic to the parent implementation.
GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, state, TargetLV, Val); GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, state, TargetLV, Val);
@ -1765,9 +1741,9 @@ const GRState* CFRefCount::HandleSymbolDeath(GRStateManager& VMgr,
GRStateRef state(St, VMgr); GRStateRef state(St, VMgr);
if (!hasLeak) if (!hasLeak)
return state.remove<RefBindings>(sid, RefBFactory); return state.remove<RefBindings>(sid);
return state.set<RefBindings>(sid, V ^ RefVal::ErrorLeak, RefBFactory); return state.set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
} }
void CFRefCount::EvalEndPath(GRExprEngine& Eng, void CFRefCount::EvalEndPath(GRExprEngine& Eng,
@ -1899,7 +1875,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
} }
// Update the binding. // Update the binding.
state = state.set<RefBindings>(Sym, X, RefBFactory); state = state.set<RefBindings>(Sym, X);
Builder.MakeNode(Dst, S, Pred, state); Builder.MakeNode(Dst, S, Pred, state);
} }
@ -1922,6 +1898,9 @@ const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
return St; return St;
bool changed = false; bool changed = false;
GRStateRef state(St, VMgr);
RefBindings::Factory& RefBFactory = state.get_context<RefBindings>();
for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) { for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
// Check if the symbol is null (or equal to any constant). // Check if the symbol is null (or equal to any constant).
@ -1932,17 +1911,16 @@ const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
} }
} }
if (!changed) if (changed)
return St; state = state.set<RefBindings>(B);
GRStateRef state(St, VMgr);
state = state.set<RefBindings>(B);
return state; return state;
} }
RefBindings CFRefCount::Update(RefBindings B, SymbolID sym, RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
RefVal V, ArgEffect E, 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 // FIXME: This dispatch can potentially be sped up by unifiying it into
// a single switch statement. Opt for simplicity for now. // a single switch statement. Opt for simplicity for now.