[analyzer] Convert more functions (ex:evalBind()) to iterative builders
llvm-svn: 142829
This commit is contained in:
parent
f011a4a6f9
commit
cbdf10be19
|
|
@ -301,6 +301,10 @@ public:
|
||||||
const NodeBuilderContext &Ctx)
|
const NodeBuilderContext &Ctx)
|
||||||
: NodeBuilder(SrcNode, DstSet, Ctx) {}
|
: NodeBuilder(SrcNode, DstSet, Ctx) {}
|
||||||
|
|
||||||
|
PureStmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
|
||||||
|
const NodeBuilderContext &Ctx)
|
||||||
|
: NodeBuilder(SrcSet, DstSet, Ctx) {}
|
||||||
|
|
||||||
ExplodedNode *generateNode(const Stmt *S,
|
ExplodedNode *generateNode(const Stmt *S,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
const ProgramState *St,
|
const ProgramState *St,
|
||||||
|
|
|
||||||
|
|
@ -1297,9 +1297,13 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
|
||||||
getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
|
getCheckerManager().runCheckersForBind(CheckedSet, Pred, location, Val,
|
||||||
StoreE, *this);
|
StoreE, *this);
|
||||||
|
|
||||||
|
// TODO: Remove TmpDst after NB refactoring is done.
|
||||||
|
ExplodedNodeSet TmpDst;
|
||||||
|
Builder->takeNodes(CheckedSet);
|
||||||
|
PureStmtNodeBuilder Bldr(CheckedSet, TmpDst, *currentBuilderContext);
|
||||||
|
|
||||||
for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
|
for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
|
||||||
I!=E; ++I) {
|
I!=E; ++I) {
|
||||||
|
|
||||||
const ProgramState *state = (*I)->getState();
|
const ProgramState *state = (*I)->getState();
|
||||||
|
|
||||||
if (atDeclInit) {
|
if (atDeclInit) {
|
||||||
|
|
@ -1311,8 +1315,10 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
|
||||||
state = state->bindLoc(location, Val);
|
state = state->bindLoc(location, Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeNode(Dst, StoreE, *I, state);
|
Bldr.generateNode(StoreE, *I, state);
|
||||||
}
|
}
|
||||||
|
Builder->addNodes(TmpDst);
|
||||||
|
Dst.insert(TmpDst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// evalStore - Handle the semantics of a store via an assignment.
|
/// evalStore - Handle the semantics of a store via an assignment.
|
||||||
|
|
|
||||||
|
|
@ -373,6 +373,8 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
|
||||||
|
|
||||||
void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
|
Builder->takeNodes(Pred);
|
||||||
|
PureStmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
assert(B->getOpcode() == BO_LAnd ||
|
assert(B->getOpcode() == BO_LAnd ||
|
||||||
B->getOpcode() == BO_LOr);
|
B->getOpcode() == BO_LOr);
|
||||||
|
|
@ -389,7 +391,8 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
||||||
|
|
||||||
// Handle undefined values.
|
// Handle undefined values.
|
||||||
if (X.isUndef()) {
|
if (X.isUndef()) {
|
||||||
MakeNode(Dst, B, Pred, state->BindExpr(B, X));
|
Bldr.generateNode(B, Pred, state->BindExpr(B, X));
|
||||||
|
Builder->addNodes(Dst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -402,11 +405,11 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
||||||
// this right now, and since most logical expressions are used for branches,
|
// this right now, and since most logical expressions are used for branches,
|
||||||
// the payoff is not likely to be large. Instead, we do eager evaluation.
|
// the payoff is not likely to be large. Instead, we do eager evaluation.
|
||||||
if (const ProgramState *newState = state->assume(XD, true))
|
if (const ProgramState *newState = state->assume(XD, true))
|
||||||
MakeNode(Dst, B, Pred,
|
Bldr.generateNode(B, Pred,
|
||||||
newState->BindExpr(B, svalBuilder.makeIntVal(1U, B->getType())));
|
newState->BindExpr(B, svalBuilder.makeIntVal(1U, B->getType())));
|
||||||
|
|
||||||
if (const ProgramState *newState = state->assume(XD, false))
|
if (const ProgramState *newState = state->assume(XD, false))
|
||||||
MakeNode(Dst, B, Pred,
|
Bldr.generateNode(B, Pred,
|
||||||
newState->BindExpr(B, svalBuilder.makeIntVal(0U, B->getType())));
|
newState->BindExpr(B, svalBuilder.makeIntVal(0U, B->getType())));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -415,13 +418,16 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
|
||||||
// the short-circuiting.
|
// the short-circuiting.
|
||||||
X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U,
|
X = svalBuilder.makeIntVal(B->getOpcode() == BO_LAnd ? 0U : 1U,
|
||||||
B->getType());
|
B->getType());
|
||||||
MakeNode(Dst, B, Pred, state->BindExpr(B, X));
|
Bldr.generateNode(B, Pred, state->BindExpr(B, X));
|
||||||
}
|
}
|
||||||
|
Builder->addNodes(Dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
|
void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
|
Builder->takeNodes(Pred);
|
||||||
|
PureStmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
const ProgramState *state = Pred->getState();
|
||||||
QualType T = getContext().getCanonicalType(IE->getType());
|
QualType T = getContext().getCanonicalType(IE->getType());
|
||||||
|
|
@ -434,7 +440,8 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
|
||||||
// e.g: static int* myArray[] = {};
|
// e.g: static int* myArray[] = {};
|
||||||
if (NumInitElements == 0) {
|
if (NumInitElements == 0) {
|
||||||
SVal V = svalBuilder.makeCompoundVal(T, vals);
|
SVal V = svalBuilder.makeCompoundVal(T, vals);
|
||||||
MakeNode(Dst, IE, Pred, state->BindExpr(IE, V));
|
B.generateNode(IE, Pred, state->BindExpr(IE, V));
|
||||||
|
Builder->addNodes(Dst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,15 +450,17 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
|
||||||
vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it)), vals);
|
vals = getBasicVals().consVals(state->getSVal(cast<Expr>(*it)), vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeNode(Dst, IE, Pred,
|
B.generateNode(IE, Pred,
|
||||||
state->BindExpr(IE, svalBuilder.makeCompoundVal(T, vals)));
|
state->BindExpr(IE, svalBuilder.makeCompoundVal(T, vals)));
|
||||||
|
Builder->addNodes(Dst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Loc::isLocType(T) || T->isIntegerType()) {
|
if (Loc::isLocType(T) || T->isIntegerType()) {
|
||||||
assert(IE->getNumInits() == 1);
|
assert(IE->getNumInits() == 1);
|
||||||
const Expr *initEx = IE->getInit(0);
|
const Expr *initEx = IE->getInit(0);
|
||||||
MakeNode(Dst, IE, Pred, state->BindExpr(IE, state->getSVal(initEx)));
|
B.generateNode(IE, Pred, state->BindExpr(IE, state->getSVal(initEx)));
|
||||||
|
Builder->addNodes(Dst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,6 +472,8 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
|
||||||
const Expr *R,
|
const Expr *R,
|
||||||
ExplodedNode *Pred,
|
ExplodedNode *Pred,
|
||||||
ExplodedNodeSet &Dst) {
|
ExplodedNodeSet &Dst) {
|
||||||
|
Builder->takeNodes(Pred);
|
||||||
|
PureStmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
||||||
|
|
||||||
const ProgramState *state = Pred->getState();
|
const ProgramState *state = Pred->getState();
|
||||||
SVal X = state->getSVal(Ex);
|
SVal X = state->getSVal(Ex);
|
||||||
|
|
@ -472,12 +483,15 @@ void ExprEngine::VisitGuardedExpr(const Expr *Ex,
|
||||||
X = state->getSVal(SE);
|
X = state->getSVal(SE);
|
||||||
|
|
||||||
// Make sure that we invalidate the previous binding.
|
// Make sure that we invalidate the previous binding.
|
||||||
MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, X, true));
|
B.generateNode(Ex, Pred, state->BindExpr(Ex, X, true));
|
||||||
|
Builder->addNodes(Dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprEngine::
|
void ExprEngine::
|
||||||
VisitOffsetOfExpr(const OffsetOfExpr *OOE,
|
VisitOffsetOfExpr(const OffsetOfExpr *OOE,
|
||||||
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
|
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
|
||||||
|
Builder->takeNodes(Pred);
|
||||||
|
PureStmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
|
||||||
Expr::EvalResult Res;
|
Expr::EvalResult Res;
|
||||||
if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) {
|
if (OOE->Evaluate(Res, getContext()) && Res.Val.isInt()) {
|
||||||
const APSInt &IV = Res.Val.getInt();
|
const APSInt &IV = Res.Val.getInt();
|
||||||
|
|
@ -485,11 +499,10 @@ VisitOffsetOfExpr(const OffsetOfExpr *OOE,
|
||||||
assert(OOE->getType()->isIntegerType());
|
assert(OOE->getType()->isIntegerType());
|
||||||
assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType());
|
assert(IV.isSigned() == OOE->getType()->isSignedIntegerOrEnumerationType());
|
||||||
SVal X = svalBuilder.makeIntVal(IV);
|
SVal X = svalBuilder.makeIntVal(IV);
|
||||||
MakeNode(Dst, OOE, Pred, Pred->getState()->BindExpr(OOE, X));
|
B.generateNode(OOE, Pred, Pred->getState()->BindExpr(OOE, X));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// FIXME: Handle the case where __builtin_offsetof is not a constant.
|
// FIXME: Handle the case where __builtin_offsetof is not a constant.
|
||||||
Dst.Add(Pred);
|
Builder->addNodes(Dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue