Remove more dependencies on GRStateRef. As a consequence, we can now

pretty-print a GRState object anywhere it is referenced (instead of
needing a GRStateRef of a GRStateManager handy).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73669 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2009-06-18 01:23:53 +00:00
Родитель 3a77203689
Коммит b65be70779
4 изменённых файлов: 140 добавлений и 137 удалений

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

@ -159,9 +159,16 @@ public:
BasicValueFactory &getBasicVals() const;
SymbolManager &getSymbolManager() const;
const GRState *bind(Loc location, SVal V) const;
const GRState *bindExpr(Stmt* Ex, SVal V, bool isBlkExpr,
bool Invalidate) const;
const GRState *bind(SVal location, SVal V) const;
const GRState *bindExpr(Stmt* Ex, SVal V, bool Invalidate = true) const;
const GRState *bindLoc(Loc location, SVal V) const;
const GRState *bindLoc(SVal location, SVal V) const;
const GRState *unbindLoc(Loc LV) const;
SVal getLValue(const VarDecl* VD) const;
@ -234,11 +241,14 @@ public:
virtual void Print(std::ostream& Out, const GRState* state,
const char* nl, const char* sep) = 0;
};
// Pretty-printing.
void print(std::ostream& Out, const char *nl = "\n",
const char *sep = "") const;
void print(std::ostream& Out, StoreManager& StoreMgr,
ConstraintManager& ConstraintMgr,
Printer **Beg = 0, Printer **End = 0,
const char* nl = "\n", const char *sep = "") const;
void printStdErr() const;
void printDOT(std::ostream& Out) const;
// Tags used for the Generic Data Map.
struct NullDerefTag {
@ -299,6 +309,7 @@ class GRStateRef;
class GRStateManager {
friend class GRExprEngine;
friend class GRState;
friend class GRStateRef;
private:
@ -507,8 +518,6 @@ public:
return St->getEnvironment().GetBlkExprSVal(Ex, getBasicVals());
}
const GRState* BindExpr(const GRState* St, Stmt* Ex, SVal V,
bool isBlkExpr, bool Invalidate) {
@ -731,12 +740,22 @@ public:
// Out-of-line method definitions for GRState.
//===----------------------------------------------------------------------===//
inline const GRState *GRState::bind(Loc LV, SVal V) const {
inline const GRState *GRState::bindExpr(Stmt* Ex, SVal V, bool isBlkExpr,
bool Invalidate) const {
return Mgr->BindExpr(this, Ex, V, isBlkExpr, Invalidate);
}
inline const GRState *GRState::bindExpr(Stmt* Ex, SVal V,
bool Invalidate) const {
return Mgr->BindExpr(this, Ex, V, Invalidate);
}
inline const GRState *GRState::bindLoc(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 const GRState *GRState::bindLoc(SVal LV, SVal V) const {
return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
}
inline SVal GRState::getLValue(const VarDecl* VD) const {
@ -820,6 +839,10 @@ CB GRState::scanReachableSymbols(SVal val) const {
Mgr->scanReachableSymbols(val, this, cb);
return cb;
}
inline const GRState *GRState::unbindLoc(Loc LV) const {
return Mgr->Unbind(this, LV);
}
//===----------------------------------------------------------------------===//
// GRStateRef - A "fat" reference to GRState that also bundles GRStateManager.
@ -957,15 +980,7 @@ public:
}
SymbolManager& getSymbolManager() { return Mgr->getSymbolManager(); }
BasicValueFactory& getBasicVals() { return Mgr->getBasicVals(); }
// Pretty-printing.
void print(std::ostream& Out, const char* nl = "\n",
const char *sep = "") const;
void printStdErr() const;
void printDOT(std::ostream& Out) const;
BasicValueFactory& getBasicVals() { return Mgr->getBasicVals(); }
};
} // end clang namespace

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

@ -1804,11 +1804,11 @@ static SymbolRef GetCurrentAutoreleasePool(const GRState* state) {
return stack.isEmpty() ? SymbolRef() : stack.getHead();
}
static GRStateRef SendAutorelease(GRStateRef state, ARCounts::Factory &F,
SymbolRef sym) {
static const GRState * SendAutorelease(const GRState *state,
ARCounts::Factory &F, SymbolRef sym) {
SymbolRef pool = GetCurrentAutoreleasePool(state);
const ARCounts *cnts = state.get<AutoreleasePoolContents>(pool);
const ARCounts *cnts = state->get<AutoreleasePoolContents>(pool);
ARCounts newCnts(0);
if (cnts) {
@ -1818,7 +1818,7 @@ static GRStateRef SendAutorelease(GRStateRef state, ARCounts::Factory &F,
else
newCnts = F.Add(F.GetEmptyMap(), sym, 1);
return state.set<AutoreleasePoolContents>(pool, newCnts);
return state->set<AutoreleasePoolContents>(pool, newCnts);
}
//===----------------------------------------------------------------------===//
@ -1851,7 +1851,7 @@ private:
BugType *returnNotOwnedForOwned;
BugReporter *BR;
GRStateRef Update(GRStateRef state, SymbolRef sym, RefVal V, ArgEffect E,
const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E,
RefVal::Kind& hasErr);
void ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
@ -1861,10 +1861,10 @@ private:
const GRState* St,
RefVal::Kind hasErr, SymbolRef Sym);
GRStateRef HandleSymbolDeath(GRStateRef state, SymbolRef sid, RefVal V,
const GRState * HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
llvm::SmallVectorImpl<SymbolRef> &Leaked);
ExplodedNode<GRState>* ProcessLeaks(GRStateRef state,
ExplodedNode<GRState>* ProcessLeaks(const GRState * state,
llvm::SmallVectorImpl<SymbolRef> &Leaked,
GenericNodeBuilder &Builder,
GRExprEngine &Eng,
@ -1939,8 +1939,8 @@ public:
Stmt* S, const GRState* state,
SymbolReaper& SymReaper);
std::pair<ExplodedNode<GRState>*, GRStateRef>
HandleAutoreleaseCounts(GRStateRef state, GenericNodeBuilder Bd,
std::pair<ExplodedNode<GRState>*, const GRState *>
HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
ExplodedNode<GRState>* Pred, GRExprEngine &Eng,
SymbolRef Sym, RefVal V, bool &stop);
// Return statements.
@ -2283,15 +2283,14 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
return NULL;
// Check if the type state has changed.
GRStateManager &StMgr = BRC.getStateManager();
GRStateRef PrevSt(PrevN->getState(), StMgr);
GRStateRef CurrSt(N->getState(), StMgr);
const GRState *PrevSt = PrevN->getState();
const GRState *CurrSt = N->getState();
const RefVal* CurrT = CurrSt.get<RefBindings>(Sym);
const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
if (!CurrT) return NULL;
const RefVal& CurrV = *CurrT;
const RefVal* PrevT = PrevSt.get<RefBindings>(Sym);
const RefVal &CurrV = *CurrT;
const RefVal *PrevT = PrevSt->get<RefBindings>(Sym);
// Create a string buffer to constain all the useful things we want
// to tell the user.
@ -2305,7 +2304,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
// Get the name of the callee (if it is available).
SVal X = CurrSt.GetSValAsScalarOrLoc(CE->getCallee());
SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee());
if (const FunctionDecl* FD = X.getAsFunctionDecl())
os << "Call to function '" << FD->getNameAsString() <<'\'';
else
@ -2362,7 +2361,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
// Retrieve the value of the argument. Is it the symbol
// we are interested in?
if (CurrSt.GetSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym)
if (CurrSt->getSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym)
continue;
// We have an argument. Get the effect!
@ -2371,7 +2370,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
}
else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
if (Expr *receiver = ME->getReceiver())
if (CurrSt.GetSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
// The symbol we are tracking is the receiver.
AEffects.push_back(Summ->getReceiverEffect());
}
@ -2399,7 +2398,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
if (contains(AEffects, MakeCollectable)) {
// Get the name of the function.
Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
SVal X = CurrSt.GetSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
const FunctionDecl* FD = X.getAsFunctionDecl();
const std::string& FName = FD->getNameAsString();
@ -2510,7 +2509,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode<GRState>* N,
// to Sym.
for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
if (Expr* Exp = dyn_cast_or_null<Expr>(*I))
if (CurrSt.GetSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) {
if (CurrSt->getSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) {
P->addRange(Exp->getSourceRange());
break;
}
@ -2762,7 +2761,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
// Get the state.
GRStateManager& StateMgr = Eng.getStateManager();
GRStateRef state(Builder.GetState(Pred), StateMgr);
const GRState *state = Builder.GetState(Pred);
ASTContext& Ctx = StateMgr.getContext();
ValueManager &ValMgr = Eng.getValueManager();
@ -2773,11 +2772,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolRef ErrorSym = 0;
for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
SVal V = state.GetSValAsScalarOrLoc(*I);
SVal V = state->getSValAsScalarOrLoc(*I);
SymbolRef Sym = V.getAsLocSymbol();
if (Sym)
if (RefBindings::data_type* T = state.get<RefBindings>(Sym)) {
if (RefBindings::data_type* T = state->get<RefBindings>(Sym)) {
state = Update(state, Sym, *T, Summ.getArg(idx), hasErr);
if (hasErr) {
ErrorExpr = *I;
@ -2832,10 +2831,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
}
// Is the invalidated variable something that we were tracking?
SymbolRef Sym = state.GetSValAsScalarOrLoc(R).getAsLocSymbol();
SymbolRef Sym = state->getSValAsScalarOrLoc(R).getAsLocSymbol();
// Remove any existing reference-count binding.
if (Sym) state = state.remove<RefBindings>(Sym);
if (Sym) state = state->remove<RefBindings>(Sym);
if (R->isBoundable(Ctx)) {
// Set the value of the variable to be a conjured symbol.
@ -2845,7 +2844,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())){
ValueManager &ValMgr = Eng.getValueManager();
SVal V = ValMgr.getConjuredSymbolVal(*I, T, Count);
state = state.BindLoc(Loc::MakeVal(R), V);
state = state->bindLoc(Loc::MakeVal(R), V);
}
else if (const RecordType *RT = T->getAsStructureType()) {
// Handle structs in a not so awesome way. Here we just
@ -2859,7 +2858,8 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (!RD)
continue;
MemRegionManager &MRMgr = state.getManager().getRegionManager();
MemRegionManager &MRMgr =
state->getStateManager().getRegionManager();
// Iterate through the fields and construct new symbols.
for (RecordDecl::field_iterator FI=RD->field_begin(Ctx),
@ -2874,7 +2874,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
const FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
SVal V = ValMgr.getConjuredSymbolVal(*I, FT, Count);
state = state.BindLoc(Loc::MakeVal(FR), V);
state = state->bindLoc(Loc::MakeVal(FR), V);
}
}
} else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
@ -2882,31 +2882,30 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
StoreManager& StoreMgr = Eng.getStateManager().getStoreManager();
SVal V = ValMgr.getConjuredSymbolVal(*I, AT->getElementType(),
Count);
state = GRStateRef(StoreMgr.setDefaultValue(state, R, V),
StateMgr);
state = StoreMgr.setDefaultValue(state, R, V);
} else {
// Just blast away other values.
state = state.BindLoc(*MR, UnknownVal());
state = state->bindLoc(*MR, UnknownVal());
}
}
}
else
state = state.BindLoc(*MR, UnknownVal());
state = state->bindLoc(*MR, UnknownVal());
}
else {
// Nuke all other arguments passed by reference.
state = state.Unbind(cast<Loc>(V));
state = state->unbindLoc(cast<Loc>(V));
}
}
else if (isa<nonloc::LocAsInteger>(V))
state = state.Unbind(cast<nonloc::LocAsInteger>(V).getLoc());
state = state->unbindLoc(cast<nonloc::LocAsInteger>(V).getLoc());
}
// Evaluate the effect on the message receiver.
if (!ErrorExpr && Receiver) {
SymbolRef Sym = state.GetSValAsScalarOrLoc(Receiver).getAsLocSymbol();
SymbolRef Sym = state->getSValAsScalarOrLoc(Receiver).getAsLocSymbol();
if (Sym) {
if (const RefVal* T = state.get<RefBindings>(Sym)) {
if (const RefVal* T = state->get<RefBindings>(Sym)) {
state = Update(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
if (hasErr) {
ErrorExpr = Receiver;
@ -2928,10 +2927,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
assert(Receiver);
SVal V = state.GetSValAsScalarOrLoc(Receiver);
SVal V = state->getSValAsScalarOrLoc(Receiver);
bool found = false;
if (SymbolRef Sym = V.getAsLocSymbol())
if (state.get<RefBindings>(Sym)) {
if (state->get<RefBindings>(Sym)) {
found = true;
RE = Summaries.getObjAllocRetEffect();
}
@ -2959,7 +2958,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
unsigned Count = Builder.getCurrentBlockCount();
ValueManager &ValMgr = Eng.getValueManager();
SVal X = ValMgr.getConjuredSymbolVal(Ex, T, Count);
state = state.BindExpr(Ex, X, false);
state = state->bindExpr(Ex, X, false);
}
break;
@ -2969,15 +2968,15 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
unsigned idx = RE.getIndex();
assert (arg_end >= arg_beg);
assert (idx < (unsigned) (arg_end - arg_beg));
SVal V = state.GetSValAsScalarOrLoc(*(arg_beg+idx));
state = state.BindExpr(Ex, V, false);
SVal V = state->getSValAsScalarOrLoc(*(arg_beg+idx));
state = state->bindExpr(Ex, V, false);
break;
}
case RetEffect::ReceiverAlias: {
assert (Receiver);
SVal V = state.GetSValAsScalarOrLoc(Receiver);
state = state.BindExpr(Ex, V, false);
SVal V = state->getSValAsScalarOrLoc(Receiver);
state = state->bindExpr(Ex, V, false);
break;
}
@ -2987,9 +2986,9 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
ValueManager &ValMgr = Eng.getValueManager();
SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
QualType RetT = GetReturnType(Ex, ValMgr.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
RetT));
state = state.BindExpr(Ex, ValMgr.makeRegionVal(Sym), false);
state = state->bindExpr(Ex, ValMgr.makeRegionVal(Sym), false);
// FIXME: Add a flag to the checker where allocations are assumed to
// *not fail.
@ -3010,9 +3009,9 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
ValueManager &ValMgr = Eng.getValueManager();
SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
QualType RetT = GetReturnType(Ex, ValMgr.getContext());
state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
RetT));
state = state.BindExpr(Ex, ValMgr.makeRegionVal(Sym), false);
state = state->bindExpr(Ex, ValMgr.makeRegionVal(Sym), false);
break;
}
}
@ -3149,7 +3148,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->bind(cast<Loc>(location), UnknownVal())));
escapes = (state == (state->bindLoc(cast<Loc>(location), UnknownVal())));
}
}
@ -3176,14 +3175,14 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
if (!RetE)
return;
GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
SymbolRef Sym = state.GetSValAsScalarOrLoc(RetE).getAsLocSymbol();
const GRState *state = Builder.GetState(Pred);
SymbolRef Sym = state->getSValAsScalarOrLoc(RetE).getAsLocSymbol();
if (!Sym)
return;
// Get the reference count binding (if any).
const RefVal* T = state.get<RefBindings>(Sym);
const RefVal* T = state->get<RefBindings>(Sym);
if (!T)
return;
@ -3217,7 +3216,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
}
// Update the binding.
state = state.set<RefBindings>(Sym, X);
state = state->set<RefBindings>(Sym, X);
Pred = Builder.MakeNode(Dst, S, Pred, state);
// Did we cache out?
@ -3236,7 +3235,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
return;
// Get the updated binding.
T = state.get<RefBindings>(Sym);
T = state->get<RefBindings>(Sym);
assert(T);
X = *T;
@ -3271,7 +3270,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
if (hasError) {
// Generate an error node.
static int ReturnOwnLeakTag = 0;
state = state.set<RefBindings>(Sym, X);
state = state->set<RefBindings>(Sym, X);
ExplodedNode<GRState> *N =
Builder.generateNode(PostStmt(S, &ReturnOwnLeakTag), state, Pred);
if (N) {
@ -3292,7 +3291,7 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
// owned object.
static int ReturnNotOwnedForOwnedTag = 0;
state = state.set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
if (ExplodedNode<GRState> *N =
Builder.generateNode(PostStmt(S, &ReturnNotOwnedForOwnedTag),
state, Pred)) {
@ -3309,9 +3308,9 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
// Assumptions.
const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
const GRState* St,
SVal Cond, bool Assumption,
bool& isFeasible) {
const GRState* state,
SVal Cond, bool Assumption,
bool& isFeasible) {
// FIXME: We may add to the interface of EvalAssume the list of symbols
// whose assumptions have changed. For now we just iterate through the
@ -3319,32 +3318,30 @@ const GRState* CFRefCount::EvalAssume(GRStateManager& VMgr,
// too bad since the number of symbols we will track in practice are
// probably small and EvalAssume is only called at branches and a few
// other places.
RefBindings B = St->get<RefBindings>();
RefBindings B = state->get<RefBindings>();
if (B.isEmpty())
return St;
return state;
bool changed = false;
GRStateRef state(St, VMgr);
RefBindings::Factory& RefBFactory = state.get_context<RefBindings>();
bool changed = false;
RefBindings::Factory& RefBFactory = state->get_context<RefBindings>();
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(St, I.getKey())) {
if (VMgr.getSymVal(state, I.getKey())) {
changed = true;
B = RefBFactory.Remove(B, I.getKey());
}
}
if (changed)
state = state.set<RefBindings>(B);
state = state->set<RefBindings>(B);
return state;
}
GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
const GRState * CFRefCount::Update(const GRState * state, SymbolRef sym,
RefVal V, ArgEffect E,
RefVal::Kind& hasErr) {
@ -3362,7 +3359,7 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
if (!isGCEnabled() && V.getKind() == RefVal::Released) {
V = V ^ RefVal::ErrorUseAfterRelease;
hasErr = V.getKind();
return state.set<RefBindings>(sym, V);
return state->set<RefBindings>(sym, V);
}
switch (E) {
@ -3384,7 +3381,7 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
// The object immediately transitions to the released state.
V = V ^ RefVal::Released;
V.clearCounts();
return state.set<RefBindings>(sym, V);
return state->set<RefBindings>(sym, V);
case RefVal::NotOwned:
V = V ^ RefVal::ErrorDeallocNotOwned;
hasErr = V.getKind();
@ -3394,7 +3391,7 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
case NewAutoreleasePool:
assert(!isGCEnabled());
return state.add<AutoreleaseStack>(sym);
return state->add<AutoreleaseStack>(sym);
case MayEscape:
if (V.getKind() == RefVal::Owned) {
@ -3418,7 +3415,7 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
break;
case StopTracking:
return state.remove<RefBindings>(sym);
return state->remove<RefBindings>(sym);
case IncRef:
switch (V.getKind()) {
@ -3470,15 +3467,15 @@ GRStateRef CFRefCount::Update(GRStateRef state, SymbolRef sym,
}
break;
}
return state.set<RefBindings>(sym, V);
return state->set<RefBindings>(sym, V);
}
//===----------------------------------------------------------------------===//
// Handle dead symbols and end-of-path.
//===----------------------------------------------------------------------===//
std::pair<ExplodedNode<GRState>*, GRStateRef>
CFRefCount::HandleAutoreleaseCounts(GRStateRef state, GenericNodeBuilder Bd,
std::pair<ExplodedNode<GRState>*, const GRState *>
CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
ExplodedNode<GRState>* Pred,
GRExprEngine &Eng,
SymbolRef Sym, RefVal V, bool &stop) {
@ -3510,7 +3507,7 @@ CFRefCount::HandleAutoreleaseCounts(GRStateRef state, GenericNodeBuilder Bd,
V.setCount(Cnt - ACnt);
V.setAutoreleaseCount(0);
}
state = state.set<RefBindings>(Sym, V);
state = state->set<RefBindings>(Sym, V);
ExplodedNode<GRState> *N = Bd.MakeNode(state, Pred);
stop = (N == 0);
return std::make_pair(N, state);
@ -3520,7 +3517,7 @@ CFRefCount::HandleAutoreleaseCounts(GRStateRef state, GenericNodeBuilder Bd,
// Emit hard error.
stop = true;
V = V ^ RefVal::ErrorOverAutorelease;
state = state.set<RefBindings>(Sym, V);
state = state->set<RefBindings>(Sym, V);
if (ExplodedNode<GRState> *N = Bd.MakeNode(state, Pred)) {
N->markAsSink();
@ -3546,22 +3543,22 @@ CFRefCount::HandleAutoreleaseCounts(GRStateRef state, GenericNodeBuilder Bd,
return std::make_pair((ExplodedNode<GRState>*)0, state);
}
GRStateRef
CFRefCount::HandleSymbolDeath(GRStateRef state, SymbolRef sid, RefVal V,
const GRState *
CFRefCount::HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
llvm::SmallVectorImpl<SymbolRef> &Leaked) {
bool hasLeak = V.isOwned() ||
((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
if (!hasLeak)
return state.remove<RefBindings>(sid);
return state->remove<RefBindings>(sid);
Leaked.push_back(sid);
return state.set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
}
ExplodedNode<GRState>*
CFRefCount::ProcessLeaks(GRStateRef state,
CFRefCount::ProcessLeaks(const GRState * state,
llvm::SmallVectorImpl<SymbolRef> &Leaked,
GenericNodeBuilder &Builder,
GRExprEngine& Eng,
@ -3591,9 +3588,9 @@ CFRefCount::ProcessLeaks(GRStateRef state,
void CFRefCount::EvalEndPath(GRExprEngine& Eng,
GREndPathNodeBuilder<GRState>& Builder) {
GRStateRef state(Builder.getState(), Eng.getStateManager());
const GRState *state = Builder.getState();
GenericNodeBuilder Bd(Builder);
RefBindings B = state.get<RefBindings>();
RefBindings B = state->get<RefBindings>();
ExplodedNode<GRState> *Pred = 0;
for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
@ -3606,7 +3603,7 @@ void CFRefCount::EvalEndPath(GRExprEngine& Eng,
return;
}
B = state.get<RefBindings>();
B = state->get<RefBindings>();
llvm::SmallVector<SymbolRef, 10> Leaked;
for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
@ -3620,11 +3617,10 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
GRStmtNodeBuilder<GRState>& Builder,
ExplodedNode<GRState>* Pred,
Stmt* S,
const GRState* St,
const GRState* state,
SymbolReaper& SymReaper) {
GRStateRef state(St, Eng.getStateManager());
RefBindings B = state.get<RefBindings>();
RefBindings B = state->get<RefBindings>();
// Update counts from autorelease pools
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
@ -3642,7 +3638,7 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
}
}
B = state.get<RefBindings>();
B = state->get<RefBindings>();
llvm::SmallVector<SymbolRef, 10> Leaked;
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
@ -3662,12 +3658,12 @@ void CFRefCount::EvalDeadSymbols(ExplodedNodeSet<GRState>& Dst,
return;
// Now generate a new node that nukes the old bindings.
RefBindings::Factory& F = state.get_context<RefBindings>();
RefBindings::Factory& F = state->get_context<RefBindings>();
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
E = SymReaper.dead_end(); I!=E; ++I) B = F.Remove(B, *I);
state = state.set<RefBindings>(B);
state = state->set<RefBindings>(B);
Builder.MakeNode(Dst, S, Pred, state);
}

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

@ -1194,14 +1194,13 @@ GRExprEngine::NodeTy* GRExprEngine::EvalLocation(Stmt* Ex, NodeTy* Pred,
// "Assume" that the pointer is NULL.
bool isFeasibleNull = false;
GRStateRef StNull = GRStateRef(Assume(state, LV, false, isFeasibleNull),
getStateManager());
const GRState *StNull = Assume(state, LV, false, isFeasibleNull);
if (isFeasibleNull) {
// 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);
StNull = StNull->set<GRState::NullDerefTag>(PersistentLV);
// We don't use "MakeNode" here because the node will be a sink
// and we have no intention of processing it later.
@ -1771,16 +1770,16 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
if (!Pred)
return;
GRStateRef state = GRStateRef(GetState(Pred), getStateManager());
const GRState *state = GetState(Pred);
// Handle the case where the container still has elements.
QualType IntTy = getContext().IntTy;
SVal TrueV = NonLoc::MakeVal(getBasicVals(), 1, IntTy);
GRStateRef hasElems = state.BindExpr(S, TrueV);
const GRState *hasElems = state->bindExpr(S, TrueV);
// Handle the case where the container has no elements.
SVal FalseV = NonLoc::MakeVal(getBasicVals(), 0, IntTy);
GRStateRef noElems = state.BindExpr(S, FalseV);
const GRState *noElems = state->bindExpr(S, FalseV);
if (loc::MemRegionVal* MV = dyn_cast<loc::MemRegionVal>(&ElementV))
if (const TypedRegion* R = dyn_cast<TypedRegion>(MV->getRegion())) {
@ -1792,11 +1791,11 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
unsigned Count = Builder->getCurrentBlockCount();
SymbolRef Sym = SymMgr.getConjuredSymbol(elem, T, Count);
SVal V = Loc::MakeVal(getStoreManager().getRegionManager().getSymbolicRegion(Sym));
hasElems = hasElems.BindLoc(ElementV, V);
hasElems = hasElems->bindLoc(ElementV, V);
// Bind the location to 'nil' on the false branch.
SVal nilV = loc::ConcreteInt(getBasicVals().getValue(0, T));
noElems = noElems.BindLoc(ElementV, nilV);
noElems = noElems->bindLoc(ElementV, nilV);
}
// Create the new nodes.
@ -3353,8 +3352,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
Out << "\\|StateID: " << (void*) N->getState() << "\\|";
GRStateRef state(N->getState(), GraphPrintCheckerState->getStateManager());
state.printDOT(Out);
const GRState *state = N->getState();
state->printDOT(Out);
Out << "\\l";
return Out.str();

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

@ -101,13 +101,9 @@ const GRState* GRState::makeWithStore(Store store) const {
// State pretty-printing.
//===----------------------------------------------------------------------===//
void GRState::print(std::ostream& Out, StoreManager& StoreMgr,
ConstraintManager& ConstraintMgr,
Printer** Beg, Printer** End,
const char* nl, const char* sep) const {
void GRState::print(std::ostream& Out, const char* nl, const char* sep) const {
// Print the store.
StoreMgr.print(getStore(), Out, nl, sep);
Mgr->getStoreManager().print(getStore(), Out, nl, sep);
// Print Subexpression bindings.
bool isFirst = true;
@ -147,24 +143,21 @@ void GRState::print(std::ostream& Out, StoreManager& StoreMgr,
I.getData().print(Out);
}
ConstraintMgr.print(this, Out, nl, sep);
Mgr->getConstraintManager().print(this, Out, nl, sep);
// Print checker-specific data.
for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
// Print checker-specific data.
for (std::vector<Printer*>::iterator I = Mgr->Printers.begin(),
E = Mgr->Printers.end(); I != E; ++I) {
(*I)->Print(Out, this, nl, sep);
}
}
void GRStateRef::printDOT(std::ostream& Out) const {
void GRState::printDOT(std::ostream& Out) const {
print(Out, "\\l", "\\|");
}
void GRStateRef::printStdErr() const {
void GRState::printStdErr() const {
print(*llvm::cerr);
}
void GRStateRef::print(std::ostream& Out, const char* nl, const char* sep)const{
GRState::Printer **beg = Mgr->Printers.empty() ? 0 : &Mgr->Printers[0];
GRState::Printer **end = !beg ? 0 : beg + Mgr->Printers.size();
St->print(Out, *Mgr->StoreMgr, *Mgr->ConstraintMgr, beg, end, nl, sep);
}
//===----------------------------------------------------------------------===//