зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
3a77203689
Коммит
b65be70779
|
@ -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);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Загрузка…
Ссылка в новой задаче