ValueState* GRExprEngine::SetRVal(ValueState* St, Expr* Ex, RVal V) {
- St = RemoveDeadBindings(St);
-
bool isBlkExpr = false;
if (Ex == CurrentStmt) {
return StateMgr.SetRVal(St, Ex, V, isBlkExpr, false);
}
-ValueState* GRExprEngine::SetRVal(ValueState* St, LVal LV, RVal RV) {
- St = RemoveDeadBindings(St);
- return StateMgr.SetRVal(St, LV, RV);
-}
-
-ValueState* GRExprEngine::SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V) {
- St = RemoveDeadBindings(St);
- return StateMgr.SetRVal(St, Ex, V, true, false);
-}
-
ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator,
bool branchTaken) {
assert (B == CurrentStmt && getCFG().isBlkExpr(B));
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
RVal X = GetBlkExprRVal(St, B);
assert (X.isUndef());
// Create the cleaned state.
- RDBInState = StmtEntryNode->getState();
- RDBOutState = StateMgr.RemoveDeadBindings(RDBInState, CurrentStmt, Liveness);
+ CleanedState = StateMgr.RemoveDeadBindings(StmtEntryNode->getState(),
+ CurrentStmt, Liveness);
// Visit the statement.
// If no nodes were generated, generate a new node that has all the
// dead mappings removed.
- if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
- ValueState* St = RemoveDeadBindings(StmtEntryNode->getState());
- builder.generateNode(S, St, StmtEntryNode);
- }
+ if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode)
+ builder.generateNode(S, GetState(StmtEntryNode), StmtEntryNode);
- // For safety, NULL out these variables.
+ // NULL out these variables to cleanup.
CurrentStmt = NULL;
StmtEntryNode = NULL;
Builder = NULL;
- RDBInState = NULL;
- RDBOutState = NULL;
+ CleanedState = NULL;
}
void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst){
// If we are here, we are loading the value of the decl and binding
// it to the block-level expression.
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
RVal X = RVal::MakeVal(BasicVals, D);
RVal Y = isa<lval::DeclVal>(X) ? GetRVal(St, cast<lval::DeclVal>(X)) : X;
Nodify(Dst, D, Pred, SetBlkExprRVal(St, D, Y));
// Finally, evaluate the function call.
for (NodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end(); DI!=DE; ++DI) {
- ValueState* St = (*DI)->getState();
+ ValueState* St = GetState(*DI);
RVal L = GetLVal(St, Callee);
// FIXME: Add support for symbolic function calls (calls involving
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
I != E; ++I) {
- if (GetRVal((*DI)->getState(), *I).isUndef()) {
- NodeTy* N = Builder->generateNode(CE, (*DI)->getState(), *DI);
+ if (GetRVal(GetState(*DI), *I).isUndef()) {
+ NodeTy* N = Builder->generateNode(CE, GetState(*DI), *DI);
if (N) {
N->markAsSink();
for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) {
NodeTy* N = *I1;
- ValueState* St = N->getState();
+ ValueState* St = GetState(N);
RVal V = T->isReferenceType() ? GetLVal(St, Ex) : GetRVal(St, Ex);
void GRExprEngine::VisitDeclStmt(DeclStmt* DS, GRExprEngine::NodeTy* Pred,
GRExprEngine::NodeSet& Dst) {
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
for (const ScopedDecl* D = DS->getDecl(); D; D = D->getNextDeclarator())
if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
assert (Ex == CurrentStmt && getCFG().isBlkExpr(Ex));
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
RVal X = GetBlkExprRVal(St, Ex);
assert (X.isUndef());
size = getContext().getTypeSize(T) / 8;
Nodify(Dst, Ex, Pred,
- SetRVal(Pred->getState(), Ex,
+ SetRVal(GetState(Pred), Ex,
NonLVal::MakeVal(BasicVals, size, Ex->getType())));
}
for (NodeSet::iterator I = DstTmp.begin(), DE = DstTmp.end(); I != DE; ++I) {
NodeTy* N = *I;
- ValueState* St = N->getState();
+ ValueState* St = GetState(N);
// FIXME: Bifurcate when dereferencing a symbolic with no constraints?
for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1) {
NodeTy* N1 = *I1;
- ValueState* St = N1->getState();
+ ValueState* St = GetState(N1);
RVal SubV = use_GetLVal ? GetLVal(St, U->getSubExpr()) :
GetRVal(St, U->getSubExpr());
return;
uint64_t size = getContext().getTypeSize(T) / 8;
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
St = SetRVal(St, U, NonLVal::MakeVal(BasicVals, size, U->getType()));
Nodify(Dst, U, Pred, St);
// so we use GetLVal instead of GetRVal so that DeclRefExpr's are
// evaluated to LValDecl's instead of to an NonLVal.
- RVal LeftV = B->isAssignmentOp() ? GetLVal(N1->getState(), B->getLHS())
- : GetRVal(N1->getState(), B->getLHS());
+ RVal LeftV = B->isAssignmentOp() ? GetLVal(GetState(N1), B->getLHS())
+ : GetRVal(GetState(N1), B->getLHS());
// Visit the RHS...
for (NodeSet::iterator I2 = S2.begin(), E2 = S2.end(); I2 != E2; ++I2) {
NodeTy* N2 = *I2;
- ValueState* St = N2->getState();
+ ValueState* St = GetState(N2);
Expr* RHS = B->getRHS();
RVal RightV = GetRVal(St, RHS);
// Fetch the value of the LHS (the value of the variable, etc.).
- RVal V = GetRVal(N1->getState(), LeftLV, B->getLHS()->getType());
+ RVal V = GetRVal(GetState(N1), LeftLV, B->getLHS()->getType());
// Propagate undefined value (left-side). We
// propogate undefined values for the RHS below when
}
void GRExprEngine::HandleUndefinedStore(Stmt* S, NodeTy* Pred) {
- NodeTy* N = Builder->generateNode(S, Pred->getState(), Pred);
+ NodeTy* N = Builder->generateNode(S, GetState(Pred), Pred);
N->markAsSink();
UndefStores.insert(N);
}
break;
}
else if (B->getOpcode() == BinaryOperator::Comma) {
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
Nodify(Dst, B, Pred, SetRVal(St, B, GetRVal(St, B->getRHS())));
break;
}
case Stmt::StmtExprClass: {
StmtExpr* SE = cast<StmtExpr>(S);
- ValueState* St = Pred->getState();
+ ValueState* St = GetState(Pred);
Expr* LastExpr = cast<Expr>(*SE->getSubStmt()->body_rbegin());
Nodify(Dst, SE, Pred, SetRVal(St, SE, GetRVal(St, LastExpr)));
break;
/// StmtEntryNode - The immediate predecessor node.
NodeTy* StmtEntryNode;
+ /// CleanedState - The state for StmtEntryNode "cleaned" of all dead
+ /// variables and symbols (as determined by a liveness analysis).
+ ValueState* CleanedState;
+
/// CurrentStmt - The current block-level statement.
Stmt* CurrentStmt;
/// where a pass-by-value argument has an undefined value.
UndefArgsTy UndefArgs;
- ValueState* RDBInState;
- ValueState* RDBOutState;
-
public:
GRExprEngine(GraphTy& g) :
- G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
- Builder(NULL),
- StateMgr(G.getContext(), G.getAllocator()),
- BasicVals(StateMgr.getBasicValueFactory()),
- TF(NULL), // FIXME.
- SymMgr(StateMgr.getSymbolManager()),
- StmtEntryNode(NULL), CurrentStmt(NULL) {
+ G(g), Liveness(G.getCFG(), G.getFunctionDecl()),
+ Builder(NULL),
+ StateMgr(G.getContext(), G.getAllocator()),
+ BasicVals(StateMgr.getBasicValueFactory()),
+ TF(NULL), // FIXME.
+ SymMgr(StateMgr.getSymbolManager()),
+ StmtEntryNode(NULL), CleanedState(NULL), CurrentStmt(NULL) {
// Compute liveness information.
Liveness.runOnCFG(G.getCFG());
protected:
- /// RemoveDeadBindings - Return a new state that is the same as 'St' except
- /// that all subexpression mappings are removed and that any
- /// block-level expressions that are not live at 'CurrentStmt' also have
- /// their mappings removed.
- ValueState* RemoveDeadBindings(ValueState* St) {
- assert (St);
- return St == RDBInState ? RDBOutState : St;
+ ValueState* GetState(NodeTy* N) {
+ return N == StmtEntryNode ? CleanedState : N->getState();
}
ValueState* SetRVal(ValueState* St, Expr* Ex, RVal V);
return SetRVal(St, const_cast<Expr*>(Ex), V);
}
- ValueState* SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V);
+ ValueState* SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V) {
+ return StateMgr.SetRVal(St, Ex, V, true, false);
+ }
- ValueState* SetRVal(ValueState* St, LVal LV, RVal V);
+ ValueState* SetRVal(ValueState* St, LVal LV, RVal V) {
+ return StateMgr.SetRVal(St, LV, V);
+ }
RVal GetRVal(ValueState* St, Expr* Ex) {
return StateMgr.GetRVal(St, Ex);