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) {
else
newCnts = F.Add(F.GetEmptyMap(), sym, 1);
- return state.set<AutoreleasePoolContents>(pool, newCnts);
+ return state->set<AutoreleasePoolContents>(pool, newCnts);
}
//===----------------------------------------------------------------------===//
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,
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,
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.
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.
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
// 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!
}
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());
}
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();
// 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;
}
// 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();
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;
}
// 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.
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
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),
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)) {
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;
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();
}
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;
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;
}
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.
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;
}
}
// 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())));
}
}
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;
}
// 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?
return;
// Get the updated binding.
- T = state.get<RefBindings>(Sym);
+ T = state->get<RefBindings>(Sym);
assert(T);
X = *T;
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) {
// 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)) {
// 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
// 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;
-
- bool changed = false;
+ return state;
- 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) {
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) {
// 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();
case NewAutoreleasePool:
assert(!isGCEnabled());
- return state.add<AutoreleaseStack>(sym);
+ return state->add<AutoreleaseStack>(sym);
case MayEscape:
if (V.getKind() == RefVal::Owned) {
break;
case StopTracking:
- return state.remove<RefBindings>(sym);
+ return state->remove<RefBindings>(sym);
case IncRef:
switch (V.getKind()) {
}
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) {
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);
// 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();
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,
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) {
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)
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(),
}
}
- B = state.get<RefBindings>();
+ B = state->get<RefBindings>();
llvm::SmallVector<SymbolRef, 10> Leaked;
for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
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);
}