[analyzer] Pull Pred out of NodeBuilderContext.
Each builder will have a different one, so it doesn't make sense to keep it in the context. llvm-svn: 142447
This commit is contained in:
parent
2e2eb49f7f
commit
eebbbc7253
|
|
@ -50,8 +50,8 @@ public:
|
||||||
Location(loc),
|
Location(loc),
|
||||||
ST(st),
|
ST(st),
|
||||||
size(Dst.size()),
|
size(Dst.size()),
|
||||||
Ctx(builder.Eng, pred, builder.getBlock()),
|
Ctx(builder.Eng, builder.getBlock()),
|
||||||
NB(Ctx),
|
NB(Ctx, pred),
|
||||||
respondsToCallback(respondsToCB) {
|
respondsToCallback(respondsToCB) {
|
||||||
assert(!(ST && ST != Pred->getState()));
|
assert(!(ST && ST != Pred->getState()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -170,10 +170,9 @@ public:
|
||||||
|
|
||||||
struct NodeBuilderContext {
|
struct NodeBuilderContext {
|
||||||
CoreEngine &Eng;
|
CoreEngine &Eng;
|
||||||
ExplodedNode *Pred;
|
|
||||||
const CFGBlock *Block;
|
const CFGBlock *Block;
|
||||||
NodeBuilderContext(CoreEngine &E, ExplodedNode *N, const CFGBlock *B)
|
NodeBuilderContext(CoreEngine &E, const CFGBlock *B)
|
||||||
: Eng(E), Pred(N), Block(B) { assert(B); assert(!N->isSink()); }
|
: Eng(E), Block(B) { assert(B); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is the simplest builder which generates nodes in the ExplodedGraph.
|
/// This is the simplest builder which generates nodes in the ExplodedGraph.
|
||||||
|
|
@ -181,6 +180,7 @@ class NodeBuilder {
|
||||||
protected:
|
protected:
|
||||||
friend class StmtNodeBuilder;
|
friend class StmtNodeBuilder;
|
||||||
|
|
||||||
|
ExplodedNode *BuilderPred;
|
||||||
NodeBuilderContext &C;
|
NodeBuilderContext &C;
|
||||||
bool Finalized;
|
bool Finalized;
|
||||||
|
|
||||||
|
|
@ -212,8 +212,11 @@ protected:
|
||||||
bool MarkAsSink = false);
|
bool MarkAsSink = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeBuilder(NodeBuilderContext &Ctx)
|
NodeBuilder(NodeBuilderContext &Ctx, ExplodedNode *N)
|
||||||
: C(Ctx), Finalized(false) { Deferred.insert(C.Pred); }
|
: BuilderPred(N), C(Ctx), Finalized(false) {
|
||||||
|
assert(!N->isSink());
|
||||||
|
Deferred.insert(N);
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~NodeBuilder() {}
|
virtual ~NodeBuilder() {}
|
||||||
|
|
||||||
|
|
@ -229,10 +232,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// \brief Get the builder's predecessor - the parent to all the other nodes.
|
// \brief Get the builder's predecessor - the parent to all the other nodes.
|
||||||
const ExplodedNode *getPred() const { return C.Pred; }
|
const ExplodedNode *getPred() const { return BuilderPred; }
|
||||||
|
|
||||||
bool hasGeneratedNodes() const {
|
bool hasGeneratedNodes() const {
|
||||||
return (!Deferred.count(C.Pred));
|
return (!Deferred.count(BuilderPred));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef DeferredTy::iterator iterator;
|
typedef DeferredTy::iterator iterator;
|
||||||
|
|
@ -251,11 +254,11 @@ public:
|
||||||
/// visited on the exploded graph path.
|
/// visited on the exploded graph path.
|
||||||
unsigned getCurrentBlockCount() const {
|
unsigned getCurrentBlockCount() const {
|
||||||
return getBlockCounter().getNumVisited(
|
return getBlockCounter().getNumVisited(
|
||||||
C.Pred->getLocationContext()->getCurrentStackFrame(),
|
BuilderPred->getLocationContext()->getCurrentStackFrame(),
|
||||||
C.Block->getBlockID());
|
C.Block->getBlockID());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExplodedNode *getPredecessor() const { return C.Pred; }
|
ExplodedNode *getPredecessor() const { return BuilderPred; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommonNodeBuilder {
|
class CommonNodeBuilder {
|
||||||
|
|
@ -400,15 +403,15 @@ class BranchNodeBuilder: public NodeBuilder {
|
||||||
void finalizeResults() {
|
void finalizeResults() {
|
||||||
if (Finalized)
|
if (Finalized)
|
||||||
return;
|
return;
|
||||||
if (!GeneratedTrue) generateNode(C.Pred->State, true);
|
if (!GeneratedTrue) generateNode(BuilderPred->State, true);
|
||||||
if (!GeneratedFalse) generateNode(C.Pred->State, false);
|
if (!GeneratedFalse) generateNode(BuilderPred->State, false);
|
||||||
Finalized = true;
|
Finalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BranchNodeBuilder(NodeBuilderContext &C, const CFGBlock *dstT,
|
BranchNodeBuilder(NodeBuilderContext &C, ExplodedNode *Pred,
|
||||||
const CFGBlock *dstF)
|
const CFGBlock *dstT, const CFGBlock *dstF)
|
||||||
: NodeBuilder(C), DstT(dstT), DstF(dstF),
|
: NodeBuilder(C, Pred), DstT(dstT), DstF(dstF),
|
||||||
GeneratedTrue(false), GeneratedFalse(false),
|
GeneratedTrue(false), GeneratedFalse(false),
|
||||||
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
|
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@ public:
|
||||||
/// nodes by processing the 'effects' of a branch condition.
|
/// nodes by processing the 'effects' of a branch condition.
|
||||||
void processBranch(const Stmt *Condition, const Stmt *Term,
|
void processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
NodeBuilderContext& BuilderCtx,
|
NodeBuilderContext& BuilderCtx,
|
||||||
|
ExplodedNode *Pred,
|
||||||
const CFGBlock *DstT,
|
const CFGBlock *DstT,
|
||||||
const CFGBlock *DstF);
|
const CFGBlock *DstF);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ public:
|
||||||
/// nodes by processing the 'effects' of a branch condition.
|
/// nodes by processing the 'effects' of a branch condition.
|
||||||
virtual void processBranch(const Stmt *Condition, const Stmt *Term,
|
virtual void processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
NodeBuilderContext& BuilderCtx,
|
NodeBuilderContext& BuilderCtx,
|
||||||
|
ExplodedNode *Pred,
|
||||||
const CFGBlock *DstT,
|
const CFGBlock *DstT,
|
||||||
const CFGBlock *DstF) = 0;
|
const CFGBlock *DstF) = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -417,8 +417,8 @@ void CoreEngine::HandleBlockExit(const CFGBlock * B, ExplodedNode *Pred) {
|
||||||
void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term,
|
void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term,
|
||||||
const CFGBlock * B, ExplodedNode *Pred) {
|
const CFGBlock * B, ExplodedNode *Pred) {
|
||||||
assert(B->succ_size() == 2);
|
assert(B->succ_size() == 2);
|
||||||
NodeBuilderContext Ctx(*this, Pred, B);
|
NodeBuilderContext Ctx(*this, B);
|
||||||
SubEng.processBranch(Cond, Term, Ctx,
|
SubEng.processBranch(Cond, Term, Ctx, Pred,
|
||||||
*(B->succ_begin()), *(B->succ_begin()+1));
|
*(B->succ_begin()), *(B->succ_begin()+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -608,11 +608,12 @@ ExplodedNode *BranchNodeBuilder::generateNode(const Stmt *Condition,
|
||||||
const ProgramState *State,
|
const ProgramState *State,
|
||||||
const ProgramPointTag *Tag,
|
const ProgramPointTag *Tag,
|
||||||
bool MarkAsSink) {
|
bool MarkAsSink) {
|
||||||
ProgramPoint PP = PostCondition(Condition, C.Pred->getLocationContext(), Tag);
|
ProgramPoint PP = PostCondition(Condition,
|
||||||
ExplodedNode *N = generateNodeImpl(PP, State, C.Pred, MarkAsSink);
|
BuilderPred->getLocationContext(), Tag);
|
||||||
|
ExplodedNode *N = generateNodeImpl(PP, State, BuilderPred, MarkAsSink);
|
||||||
assert(N);
|
assert(N);
|
||||||
// TODO: This needs to go - we should not change Pred!!!
|
// TODO: This needs to go - we should not change Pred!!!
|
||||||
C.Pred = N;
|
BuilderPred = N;
|
||||||
return N;
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -625,7 +626,7 @@ ExplodedNode *BranchNodeBuilder::generateNode(const ProgramState *State,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!NodePred)
|
if (!NodePred)
|
||||||
NodePred = C.Pred;
|
NodePred = BuilderPred;
|
||||||
ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
|
ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
|
||||||
NodePred->getLocationContext());
|
NodePred->getLocationContext());
|
||||||
ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
|
ExplodedNode *Succ = generateNodeImpl(Loc, State, NodePred);
|
||||||
|
|
|
||||||
|
|
@ -941,14 +941,15 @@ static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
|
||||||
|
|
||||||
void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
|
void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
|
||||||
NodeBuilderContext& BldCtx,
|
NodeBuilderContext& BldCtx,
|
||||||
|
ExplodedNode *Pred,
|
||||||
const CFGBlock *DstT,
|
const CFGBlock *DstT,
|
||||||
const CFGBlock *DstF) {
|
const CFGBlock *DstF) {
|
||||||
|
|
||||||
BranchNodeBuilder builder(BldCtx, DstT, DstF);
|
BranchNodeBuilder builder(BldCtx, Pred, DstT, DstF);
|
||||||
|
|
||||||
// Check for NULL conditions; e.g. "for(;;)"
|
// Check for NULL conditions; e.g. "for(;;)"
|
||||||
if (!Condition) {
|
if (!Condition) {
|
||||||
BranchNodeBuilder NullCondBldr(BldCtx, DstT, DstF);
|
BranchNodeBuilder NullCondBldr(BldCtx, Pred, DstT, DstF);
|
||||||
NullCondBldr.markInfeasible(false);
|
NullCondBldr.markInfeasible(false);
|
||||||
Engine.enqueue(NullCondBldr);
|
Engine.enqueue(NullCondBldr);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue