aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h3
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h69
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h1
-rw-r--r--lib/StaticAnalyzer/Core/CheckerContext.cpp4
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp40
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp19
8 files changed, 71 insertions, 71 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index ad587ae928..522749c37c 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -29,8 +29,6 @@ class CheckerContext {
const ProgramPoint Location;
const ProgramState *ST;
const unsigned size;
- // TODO: Use global context.
- NodeBuilderContext Ctx;
NodeBuilder &NB;
public:
bool *respondsToCallback;
@@ -48,7 +46,6 @@ public:
Location(loc),
ST(st),
size(Dst.size()),
- Ctx(builder.C.Eng, builder.getBlock(), pred),
NB(builder),
respondsToCallback(respondsToCB) {
assert(!(ST && ST != Pred->getState()));
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index b151dfef22..934d15d8cc 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -165,7 +165,7 @@ public:
}
/// Enqueue the results of the node builder onto the work list.
- void enqueue(NodeBuilder &NB);
+ void enqueue(ExplodedNodeSet &NB);
};
struct NodeBuilderContext {
@@ -181,12 +181,7 @@ class NodeBuilder {
protected:
friend class StmtNodeBuilder;
- ExplodedNode *BuilderPred;
-
-// TODO: Context should become protected after refactoring is done.
-public:
const NodeBuilderContext &C;
-protected:
/// Specifies if the builder results have been finalized. For example, if it
/// is set to false, autotransitions are yet to be generated.
@@ -196,8 +191,7 @@ protected:
/// \brief The frontier set - a set of nodes which need to be propagated after
/// the builder dies.
- typedef llvm::SmallPtrSet<ExplodedNode*,5> DeferredTy;
- DeferredTy Deferred;
+ ExplodedNodeSet &Frontier;
BlockCounter getBlockCounter() const { return C.Eng.WList->getBlockCounter();}
@@ -205,9 +199,6 @@ protected:
virtual bool checkResults() {
if (!Finalized)
return false;
- for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
- if ((*I)->isSink())
- return false;
return true;
}
@@ -220,15 +211,16 @@ protected:
bool MarkAsSink = false);
public:
- NodeBuilder(NodeBuilderContext &Ctx, bool F = true)
- : C(Ctx), Finalized(F), HasGeneratedNodes(false) {
- Deferred.insert(C.ContextPred);
+ NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+ const NodeBuilderContext &Ctx, bool F = true)
+ : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+ Frontier.insert(SrcNode);
}
- /// Create a new builder using the parent builder's context.
- NodeBuilder(const NodeBuilder &ParentBldr, bool F = true)
- : C(ParentBldr.C), Finalized(F), HasGeneratedNodes(false) {
- Deferred.insert(C.ContextPred);
+ NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+ const NodeBuilderContext &Ctx, bool F = true)
+ : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) {
+ Frontier.insert(SrcSet);
}
virtual ~NodeBuilder() {}
@@ -249,21 +241,29 @@ public:
return HasGeneratedNodes;
}
- typedef DeferredTy::iterator iterator;
+ const ExplodedNodeSet &getResults() {
+ finalizeResults();
+ assert(checkResults());
+ return Frontier;
+ }
+
+ typedef ExplodedNodeSet::iterator iterator;
/// \brief Iterators through the results frontier.
- inline iterator results_begin() {
+ inline iterator begin() {
finalizeResults();
assert(checkResults());
- return Deferred.begin();
+ return Frontier.begin();
}
- inline iterator results_end() {
+ inline iterator end() {
finalizeResults();
- return Deferred.end();
+ return Frontier.end();
}
/// \brief Return the CFGBlock associated with this builder.
const CFGBlock *getBlock() const { return C.Block; }
+ const NodeBuilderContext &getContext() { return C; }
+
/// \brief Returns the number of times the current basic block has been
/// visited on the exploded graph path.
unsigned getCurrentBlockCount() const {
@@ -297,7 +297,11 @@ public:
void GenerateAutoTransition(ExplodedNode *N);
public:
- StmtNodeBuilder(ExplodedNode *N, unsigned idx, NodeBuilderContext &Ctx);
+ StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+ unsigned idx, const NodeBuilderContext &Ctx)
+ : NodeBuilder(SrcNode, DstSet, Ctx), Idx(idx),
+ PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
+ PointKind(ProgramPoint::PostStmtKind), Tag(0) {}
~StmtNodeBuilder();
@@ -364,8 +368,8 @@ public:
void importNodesFromBuilder(const NodeBuilder &NB) {
ExplodedNode *NBPred = const_cast<ExplodedNode*>(NB.C.ContextPred);
if (NB.hasGeneratedNodes()) {
- Deferred.erase(NBPred);
- Deferred.insert(NB.Deferred.begin(), NB.Deferred.end());
+ Frontier.erase(NBPred);
+ Frontier.insert(NB.Frontier);
}
}
};
@@ -378,15 +382,16 @@ class BranchNodeBuilder: public NodeBuilder {
bool InFeasibleFalse;
public:
- BranchNodeBuilder(NodeBuilderContext &C,
+ BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
+ const NodeBuilderContext &C,
const CFGBlock *dstT, const CFGBlock *dstF)
- : NodeBuilder(C), DstT(dstT), DstF(dstF),
+ : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF),
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
- /// Create a new builder using the parent builder's context.
- BranchNodeBuilder(BranchNodeBuilder &ParentBldr)
- : NodeBuilder(ParentBldr), DstT(ParentBldr.DstT),
- DstF(ParentBldr.DstF),
+ BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
+ const NodeBuilderContext &C,
+ const CFGBlock *dstT, const CFGBlock *dstF)
+ : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF),
InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {}
ExplodedNode *generateNode(const ProgramState *State, bool branch,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 43700f8f3f..258fbeb952 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -386,6 +386,7 @@ public:
unsigned size() const { return Impl.size(); }
bool empty() const { return Impl.empty(); }
+ bool erase(ExplodedNode *N) { return Impl.erase(N); }
void clear() { Impl.clear(); }
void insert(const ExplodedNodeSet &S) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 07b2cedbd0..f18b04b8b8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -117,6 +117,10 @@ public:
BugReporter& getBugReporter() { return BR; }
StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
+ const NodeBuilderContext &getBuilderContext() {
+ assert(Builder);
+ return Builder->getContext();
+ }
bool isObjCGCEnabled() { return ObjCGCEnabled; }
@@ -163,6 +167,7 @@ public:
void processBranch(const Stmt *Condition, const Stmt *Term,
NodeBuilderContext& BuilderCtx,
ExplodedNode *Pred,
+ ExplodedNodeSet &Dst,
const CFGBlock *DstT,
const CFGBlock *DstF);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 8dfc1865bd..e891e8fc42 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -69,6 +69,7 @@ public:
virtual void processBranch(const Stmt *Condition, const Stmt *Term,
NodeBuilderContext& BuilderCtx,
ExplodedNode *Pred,
+ ExplodedNodeSet &Dst,
const CFGBlock *DstT,
const CFGBlock *DstF) = 0;
diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp
index 26479d0552..5f43b77ceb 100644
--- a/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -18,8 +18,8 @@ using namespace ento;
CheckerContext::~CheckerContext() {
// Copy the results into the Dst set.
- for (NodeBuilder::iterator I = NB.results_begin(),
- E = NB.results_end(); I != E; ++I) {
+ for (NodeBuilder::iterator I = NB.begin(),
+ E = NB.end(); I != E; ++I) {
Dst.Add(*I);
}
}
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 525bd71111..b9ab7b4c74 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -315,7 +315,8 @@ void CoreEngine::HandleBlockEntrance(const BlockEntrance &L,
// Process the entrance of the block.
if (CFGElement E = L.getFirstElement()) {
NodeBuilderContext Ctx(*this, L.getBlock(), Pred);
- StmtNodeBuilder Builder(Pred, 0, Ctx);
+ ExplodedNodeSet Dst;
+ StmtNodeBuilder Builder(Pred, Dst, 0, Ctx);
SubEng.processCFGElement(E, Builder, Pred);
}
else
@@ -419,8 +420,11 @@ void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term,
const CFGBlock * B, ExplodedNode *Pred) {
assert(B->succ_size() == 2);
NodeBuilderContext Ctx(*this, B, Pred);
- SubEng.processBranch(Cond, Term, Ctx, Pred,
+ ExplodedNodeSet Dst;
+ SubEng.processBranch(Cond, Term, Ctx, Pred, Dst,
*(B->succ_begin()), *(B->succ_begin()+1));
+ // Enqueue the new frontier onto the worklist.
+ enqueue(Dst);
}
void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
@@ -432,7 +436,8 @@ void CoreEngine::HandlePostStmt(const CFGBlock *B, unsigned StmtIdx,
HandleBlockExit(B, Pred);
else {
NodeBuilderContext Ctx(*this, B, Pred);
- StmtNodeBuilder Builder(Pred, StmtIdx, Ctx);
+ ExplodedNodeSet Dst;
+ StmtNodeBuilder Builder(Pred, Dst, StmtIdx, Ctx);
SubEng.processCFGElement((*B)[StmtIdx], Builder, Pred);
}
}
@@ -457,9 +462,9 @@ void CoreEngine::generateNode(const ProgramPoint &Loc,
if (IsNew) WList->enqueue(Node);
}
-void CoreEngine::enqueue(NodeBuilder &NB) {
- for (NodeBuilder::iterator I = NB.results_begin(),
- E = NB.results_end(); I != E; ++I) {
+void CoreEngine::enqueue(ExplodedNodeSet &S) {
+ for (ExplodedNodeSet::iterator I = S.begin(),
+ E = S.end(); I != E; ++I) {
WList->enqueue(*I);
}
}
@@ -494,28 +499,19 @@ ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
bool IsNew;
ExplodedNode *N = C.Eng.G->getNode(Loc, State, &IsNew);
N->addPredecessor(FromN, *C.Eng.G);
- Deferred.erase(FromN);
+ Frontier.erase(FromN);
if (MarkAsSink)
N->markAsSink();
-
- if (IsNew && !N->isSink())
- Deferred.insert(N);
+
+ if (IsNew)
+ Frontier.Add(N);
return (IsNew ? N : 0);
}
-
-StmtNodeBuilder::StmtNodeBuilder(ExplodedNode *N, unsigned idx,
- NodeBuilderContext &Ctx)
- : NodeBuilder(Ctx), Idx(idx),
- PurgingDeadSymbols(false), BuildSinks(false), hasGeneratedNode(false),
- PointKind(ProgramPoint::PostStmtKind), Tag(0) {
- Deferred.insert(N);
-}
-
StmtNodeBuilder::~StmtNodeBuilder() {
- for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
+ for (iterator I=Frontier.begin(), E=Frontier.end(); I!=E; ++I)
if (!(*I)->isSink())
GenerateAutoTransition(*I);
}
@@ -554,14 +550,14 @@ void StmtNodeBuilder::GenerateAutoTransition(ExplodedNode *N) {
C.Eng.WList->enqueue(Succ, C.Block, Idx+1);
}
-ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &Dst,
+ExplodedNode *StmtNodeBuilder::MakeNode(ExplodedNodeSet &DstSet,
const Stmt *S,
ExplodedNode *Pred,
const ProgramState *St,
ProgramPoint::Kind K) {
ExplodedNode *N = generateNode(S, St, Pred, K, 0, BuildSinks);
if (N && !BuildSinks){
- Dst.Add(N);
+ DstSet.Add(N);
}
return N;
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 269d7c74ee..5742266de2 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -945,15 +945,14 @@ static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr,
void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
NodeBuilderContext& BldCtx,
ExplodedNode *Pred,
+ ExplodedNodeSet &Dst,
const CFGBlock *DstT,
const CFGBlock *DstF) {
-
// Check for NULL conditions; e.g. "for(;;)"
if (!Condition) {
- BranchNodeBuilder NullCondBldr(BldCtx, DstT, DstF);
+ BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);
NullCondBldr.markInfeasible(false);
NullCondBldr.generateNode(Pred->getState(), true, Pred);
- Engine.enqueue(NullCondBldr);
return;
}
@@ -961,18 +960,19 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
Condition->getLocStart(),
"Error evaluating branch");
- NodeBuilder CheckerBldr(BldCtx);
+ ExplodedNodeSet TmpCheckersOut;
+ NodeBuilder CheckerBldr(Pred, TmpCheckersOut, BldCtx);
getCheckerManager().runCheckersForBranchCondition(Condition, CheckerBldr,
Pred, *this);
- for (NodeBuilder::iterator I = CheckerBldr.results_begin(),
- E = CheckerBldr.results_end(); E != I; ++I) {
+ BranchNodeBuilder builder(CheckerBldr.getResults(), Dst, BldCtx, DstT, DstF);
+ for (NodeBuilder::iterator I = CheckerBldr.begin(),
+ E = CheckerBldr.end(); E != I; ++I) {
ExplodedNode *PredI = *I;
if (PredI->isSink())
continue;
- BranchNodeBuilder builder(BldCtx, DstT, DstF);
const ProgramState *PrevState = Pred->getState();
SVal X = PrevState->getSVal(Condition);
@@ -998,8 +998,6 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
if (X.isUnknownOrUndef()) {
builder.generateNode(MarkBranch(PrevState, Term, true), true, PredI);
builder.generateNode(MarkBranch(PrevState, Term, false), false, PredI);
- // Enqueue the results into the work list.
- Engine.enqueue(builder);
continue;
}
@@ -1020,9 +1018,6 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
else
builder.markInfeasible(false);
}
-
- // Enqueue the results into the work list.
- Engine.enqueue(builder);
}
}