return StateMgr.SetRVal(St, LV, RV);
}
+ValueState* GRExprEngine::SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V) {
+
+ if (!StateCleaned) {
+ St = RemoveDeadBindings(CurrentStmt, St);
+ StateCleaned = true;
+ }
+
+ return StateMgr.SetRVal(St, Ex, V, true, false);
+}
+
ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator,
bool branchTaken) {
// dead mappings removed.
if (Dst.size() == 1 && *Dst.begin() == StmtEntryNode) {
- ValueState* St = RemoveDeadBindings(S, StmtEntryNode->getState());
+ ValueState* St =
+ StateCleaned ? StmtEntryNode->getState() :
+ RemoveDeadBindings(S, StmtEntryNode->getState());
+
builder.generateNode(S, St, StmtEntryNode);
}
// it to the block-level expression.
ValueState* St = Pred->getState();
- Nodify(Dst, D, Pred, SetRVal(St, D, GetRVal(St, D)));
+ 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));
}
void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred,
Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
S->printPretty(Out);
- Out << "\\lline="
- << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
- << GraphPrintSourceManager->getColumnNumber(SLoc) << "\\l";
+ if (SLoc.isFileID()) {
+ Out << "\\lline="
+ << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
+ << GraphPrintSourceManager->getColumnNumber(SLoc) << "\\l";
+ }
if (GraphPrintCheckerState->isImplicitNullDeref(N))
Out << "\\|Implicit-Null Dereference.\\l";
E.getSrc()->printTerminator(Out);
- Out << "\\lline="
- << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
- << GraphPrintSourceManager->getColumnNumber(SLoc);
+ if (SLoc.isFileID()) {
+ Out << "\\lline="
+ << GraphPrintSourceManager->getLineNumber(SLoc) << " col="
+ << GraphPrintSourceManager->getColumnNumber(SLoc);
+ }
if (isa<SwitchStmt>(T)) {
Stmt* Label = E.getDst()->getLabel();
LVal LVal::MakeVal(AddrLabelExpr* E) { return lval::GotoLabel(E->getLabel()); }
+//===----------------------------------------------------------------------===//
+// Utility methods for constructing RVals (both NonLVals and LVals).
+//===----------------------------------------------------------------------===//
+
+RVal RVal::MakeVal(BasicValueFactory& BasicVals, DeclRefExpr* E) {
+
+ ValueDecl* D = cast<DeclRefExpr>(E)->getDecl();
+
+ if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
+ return lval::DeclVal(VD);
+ }
+ else if (EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
+
+ // FIXME: Do we need to cache a copy of this enum, since it
+ // already has persistent storage? We do this because we
+ // are comparing states using pointer equality. Perhaps there is
+ // a better way, since APInts are fairly lightweight.
+
+ return nonlval::ConcreteInt(BasicVals.getValue(ED->getInitVal()));
+ }
+ else if (FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
+ return lval::FuncVal(FD);
+ }
+
+ assert (false &&
+ "ValueDecl support for this ValueDecl not implemented.");
+
+ return UnknownVal();
+}
+
//===----------------------------------------------------------------------===//
// Pretty-Printing.
//===----------------------------------------------------------------------===//
// within the referenced variables.
case Stmt::DeclRefExprClass: {
-
- ValueDecl* D = cast<DeclRefExpr>(E)->getDecl();
-
- if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
- return GetRVal(St, lval::DeclVal(VD));
- }
- else if (EnumConstantDecl* ED = dyn_cast<EnumConstantDecl>(D)) {
-
- // FIXME: Do we need to cache a copy of this enum, since it
- // already has persistent storage? We do this because we
- // are comparing states using pointer equality. Perhaps there is
- // a better way, since APInts are fairly lightweight.
- return nonlval::ConcreteInt(BasicVals.getValue(ED->getInitVal()));
- }
- else if (FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
- return lval::FuncVal(FD);
-
- assert (false &&
- "ValueDecl support for this ValueDecl not implemented.");
+ // Check if this expression is a block-level expression. If so,
+ // return its value.
+ ValueState::ExprBindingsTy::TreeTy* T=St->BlockExprBindings.SlimFind(E);
+ if (T) return T->getValue().second;
- return UnknownVal();
+ RVal X = RVal::MakeVal(BasicVals, cast<DeclRefExpr>(E));
+ return isa<lval::DeclVal>(X) ? GetRVal(St, cast<lval::DeclVal>(X)) : X;
}
case Stmt::CharacterLiteralClass: {
return SetRVal(St, const_cast<Expr*>(Ex), V);
}
- ValueState* SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V) {
- return StateMgr.SetRVal(St, Ex, V, true, false);
- }
-
-#if 0
- /// SetRVal - This version of SetRVal is used to batch process a set
- /// of different possible RVals and return a set of different states.
- const ValueState*::BufferTy& SetRVal(ValueState* St, Expr* Ex,
- const RVal::BufferTy& V,
- ValueState*::BufferTy& RetBuf);
-#endif
+ ValueState* SetBlkExprRVal(ValueState* St, Expr* Ex, RVal V);
ValueState* SetRVal(ValueState* St, LVal LV, RVal V);
symbol_iterator symbol_begin() const;
symbol_iterator symbol_end() const;
+ static RVal MakeVal(BasicValueFactory& BasicVals, DeclRefExpr* E);
+
// Implement isa<T> support.
static inline bool classof(const RVal*) { return true; }
};