[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:
Anna Zaks 2011-10-18 23:06:16 +00:00
parent 2e2eb49f7f
commit eebbbc7253
6 changed files with 31 additions and 24 deletions

View File

@ -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()));
} }

View File

@ -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) {
} }

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;