summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2011-10-26 21:06:22 +0000
committerAnna Zaks <ganna@apple.com>2011-10-26 21:06:22 +0000
commitb31d0143ddc46e41eb8378be433b65d3ec7d9c78 (patch)
tree51c639fb5b87361082270d7d4cfcbcc64697d6dc /clang
parent63f8cc6acaee2edbc49a2ff1aa7c5a09b3585d39 (diff)
downloadbcm5719-llvm-b31d0143ddc46e41eb8378be433b65d3ec7d9c78.tar.gz
bcm5719-llvm-b31d0143ddc46e41eb8378be433b65d3ec7d9c78.zip
[analyzer] GenericNodeBuilder -> NodeBuilder.
Remove GenericNodeBuilder and use a class inherited from NodeBuilder instead. llvm-svn: 143057
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h77
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h3
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h4
-rw-r--r--clang/lib/StaticAnalyzer/Core/CoreEngine.cpp51
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp15
5 files changed, 51 insertions, 99 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 5fddb75d1f3..192e1e4bee1 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -168,6 +168,7 @@ public:
void enqueue(ExplodedNodeSet &NB);
};
+// TODO: Turn into a calss.
struct NodeBuilderContext {
CoreEngine &Eng;
const CFGBlock *Block;
@@ -175,6 +176,8 @@ struct NodeBuilderContext {
NodeBuilderContext(CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
: Eng(E), Block(B), Pred(N) { assert(B); assert(!N->isSink()); }
+ ExplodedNode *getPred() const { return Pred; }
+
/// \brief Return the CFGBlock associated with this builder.
const CFGBlock *getBlock() const { return Block; }
@@ -288,6 +291,34 @@ public:
void addNodes(ExplodedNode *N) { Frontier.Add(N); }
};
+/// \class NodeBuilderWithSinks
+/// \brief This node builder keeps track of the generated sink nodes.
+class NodeBuilderWithSinks: public NodeBuilder {
+protected:
+ SmallVector<ExplodedNode*, 2> sinksGenerated;
+ ProgramPoint &Location;
+
+public:
+ NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
+ const NodeBuilderContext &Ctx, ProgramPoint &L)
+ : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
+ ExplodedNode *generateNode(const ProgramState *State,
+ ExplodedNode *Pred,
+ const ProgramPointTag *Tag = 0,
+ bool MarkAsSink = false) {
+ ProgramPoint LocalLoc = (Tag ? Location.withTag(Tag): Location);
+
+ ExplodedNode *N = generateNodeImpl(LocalLoc, State, Pred, MarkAsSink);
+ if (N && N->isSink())
+ sinksGenerated.push_back(N);
+ return N;
+ }
+
+ const SmallVectorImpl<ExplodedNode*> &getSinks() const {
+ return sinksGenerated;
+ }
+};
+
/// \class StmtNodeBuilder
/// \brief This builder class is useful for generating nodes that resulted from
/// visiting a statement. The main difference from it's parent NodeBuilder is
@@ -467,52 +498,6 @@ public:
const ProgramState *getState() const { return Pred->State; }
};
-class GenericNodeBuilderImpl {
-protected:
- CoreEngine &engine;
- ExplodedNode *pred;
- ProgramPoint pp;
- SmallVector<ExplodedNode*, 2> sinksGenerated;
-
- ExplodedNode *generateNodeImpl(const ProgramState *state,
- ExplodedNode *pred,
- ProgramPoint programPoint,
- bool asSink);
-
- GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p)
- : engine(eng), pred(pr), pp(p), hasGeneratedNode(false) {}
-
-public:
- bool hasGeneratedNode;
-
- WorkList &getWorkList() { return *engine.WList; }
-
- ExplodedNode *getPredecessor() const { return pred; }
-
- BlockCounter getBlockCounter() const {
- return engine.WList->getBlockCounter();
- }
-
- const SmallVectorImpl<ExplodedNode*> &sinks() const {
- return sinksGenerated;
- }
-};
-
-template <typename PP_T>
-class GenericNodeBuilder : public GenericNodeBuilderImpl {
-public:
- GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP_T &p)
- : GenericNodeBuilderImpl(eng, pr, p) {}
-
- ExplodedNode *generateNode(const ProgramState *state, ExplodedNode *pred,
- const ProgramPointTag *tag, bool asSink) {
- return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag),
- asSink);
- }
-
- const PP_T &getProgramPoint() const { return cast<PP_T>(pp); }
-};
-
class CallEnterNodeBuilder {
CoreEngine &Eng;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 325d824090d..7409b19e4e4 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -161,8 +161,7 @@ public:
ExplodedNode *Pred, ExplodedNodeSet &Dst);
/// Called by CoreEngine when processing the entrance of a CFGBlock.
- virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
- GenericNodeBuilder<BlockEntrance> &nodeBuilder);
+ virtual void processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder);
/// ProcessBranch - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index c35e6cca413..d258b2c8074 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -40,6 +40,7 @@ class SwitchNodeBuilder;
class EndOfFunctionNodeBuilder;
class CallEnterNodeBuilder;
class CallExitNodeBuilder;
+class NodeBuilderWithSinks;
class MemRegion;
class SubEngine {
@@ -60,8 +61,7 @@ public:
/// Called by CoreEngine when it starts processing a CFGBlock. The
/// SubEngine is expected to populate dstNodes with new nodes representing
/// updated analysis state, or generate no nodes at all if it doesn't.
- virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
- GenericNodeBuilder<BlockEntrance> &nodeBuilder) = 0;
+ virtual void processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) = 0;
/// Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 6b8c7df224e..f6939172427 100644
--- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -261,6 +261,7 @@ void CoreEngine::HandleCallExit(const CallExit &L, ExplodedNode *Pred) {
void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) {
const CFGBlock *Blk = L.getDst();
+ NodeBuilderContext BuilderCtx(*this, Blk, Pred);
// Check if we are entering the EXIT block.
if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
@@ -269,35 +270,30 @@ void CoreEngine::HandleBlockEdge(const BlockEdge &L, ExplodedNode *Pred) {
&& "EXIT block cannot contain Stmts.");
// Process the final state transition.
- NodeBuilderContext BuilderCtx(*this, Blk, Pred);
SubEng.processEndOfFunction(BuilderCtx);
// This path is done. Don't enqueue any more nodes.
return;
}
- // Call into the subengine to process entering the CFGBlock.
+ // Call into the SubEngine to process entering the CFGBlock.
ExplodedNodeSet dstNodes;
BlockEntrance BE(Blk, Pred->getLocationContext());
- GenericNodeBuilder<BlockEntrance> nodeBuilder(*this, Pred, BE);
- SubEng.processCFGBlockEntrance(dstNodes, nodeBuilder);
+ NodeBuilderWithSinks nodeBuilder(Pred, dstNodes, BuilderCtx, BE);
+ SubEng.processCFGBlockEntrance(nodeBuilder);
- if (dstNodes.empty()) {
- if (!nodeBuilder.hasGeneratedNode) {
- // Auto-generate a node and enqueue it to the worklist.
- generateNode(BE, Pred->State, Pred);
- }
- }
- else {
- for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
- I != E; ++I) {
- WList->enqueue(*I);
- }
+ // Auto-generate a node.
+ if (!nodeBuilder.hasGeneratedNodes()) {
+ nodeBuilder.generateNode(Pred->State, Pred);
}
+ // Enqueue nodes onto the worklist.
+ enqueue(dstNodes);
+
+ // Make sink nodes as exhausted.
+ const SmallVectorImpl<ExplodedNode*> &Sinks = nodeBuilder.getSinks();
for (SmallVectorImpl<ExplodedNode*>::const_iterator
- I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
- I != E; ++I) {
+ I =Sinks.begin(), E = Sinks.end(); I != E; ++I) {
blocksExhausted.push_back(std::make_pair(L, *I));
}
}
@@ -465,27 +461,6 @@ void CoreEngine::enqueue(ExplodedNodeSet &S) {
}
}
-ExplodedNode *
-GenericNodeBuilderImpl::generateNodeImpl(const ProgramState *state,
- ExplodedNode *pred,
- ProgramPoint programPoint,
- bool asSink) {
-
- hasGeneratedNode = true;
- bool isNew;
- ExplodedNode *node = engine.getGraph().getNode(programPoint, state, &isNew);
- if (pred)
- node->addPredecessor(pred, engine.getGraph());
- if (isNew) {
- if (asSink) {
- node->markAsSink();
- sinksGenerated.push_back(node);
- }
- return node;
- }
- return 0;
-}
-
ExplodedNode* NodeBuilder::generateNodeImpl(const ProgramPoint &Loc,
const ProgramState *State,
ExplodedNode *FromN,
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 0eacb31b282..24fa04bd564 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -909,20 +909,13 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
}
}
-//===----------------------------------------------------------------------===//
-// Block entrance. (Update counters).
-//===----------------------------------------------------------------------===//
-
-void ExprEngine::processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
- GenericNodeBuilder<BlockEntrance> &nodeBuilder){
+/// Block entrance. (Update counters).
+void ExprEngine::processCFGBlockEntrance(NodeBuilderWithSinks &nodeBuilder) {
// FIXME: Refactor this into a checker.
- const CFGBlock *block = nodeBuilder.getProgramPoint().getBlock();
- ExplodedNode *pred = nodeBuilder.getPredecessor();
+ ExplodedNode *pred = nodeBuilder.getContext().getPred();
- if (nodeBuilder.getBlockCounter().getNumVisited(
- pred->getLocationContext()->getCurrentStackFrame(),
- block->getBlockID()) >= AMgr.getMaxVisit()) {
+ if (nodeBuilder.getContext().getCurrentBlockCount() >= AMgr.getMaxVisit()) {
static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
nodeBuilder.generateNode(pred->getState(), pred, &tag, true);
}
OpenPOWER on IntegriCloud