[cfe-commits] r123217 - in /cfe/trunk: include/clang/StaticAnalyzer/PathSensitive/CoreEngine.h include/clang/StaticAnalyzer/PathSensitive/ExprEngine.h include/clang/StaticAnalyzer/PathSensitive/SubEngine.h lib/StaticAnalyzer/Checkers/ExprEngine.cpp lib/StaticAnalyzer/CoreEngine.cpp test/Analysis/retain-release-region-store.m
Ted Kremenek
kremenek at apple.com
Mon Jan 10 22:37:47 PST 2011
Author: kremenek
Date: Tue Jan 11 00:37:47 2011
New Revision: 123217
URL: http://llvm.org/viewvc/llvm-project?rev=123217&view=rev
Log:
Rework ExprEngine::processCFGBlockEntrance()
to use a node builder. This paves the way
for Checkers to interpose (via a "visit" method)
at the entrance to blocks.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/CoreEngine.h
cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExprEngine.h
cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/SubEngine.h
cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/CoreEngine.cpp
cfe/trunk/test/Analysis/retain-release-region-store.m
Modified: cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/CoreEngine.h?rev=123217&r1=123216&r2=123217&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/CoreEngine.h Tue Jan 11 00:37:47 2011
@@ -37,6 +37,7 @@
/// any transfer function logic and the sub-expression level (if any).
class CoreEngine {
friend class StmtNodeBuilder;
+ friend class GenericNodeBuilderImpl;
friend class BranchNodeBuilder;
friend class IndirectGotoNodeBuilder;
friend class SwitchNodeBuilder;
@@ -397,6 +398,50 @@
const GRState* getState() const { return Pred->State; }
};
+class GenericNodeBuilderImpl {
+protected:
+ CoreEngine &engine;
+ ExplodedNode *pred;
+ bool HasGeneratedNode;
+ ProgramPoint pp;
+ llvm::SmallVector<ExplodedNode*, 2> sinksGenerated;
+
+ ExplodedNode *generateNodeImpl(const GRState *state, ExplodedNode *pred,
+ ProgramPoint programPoint, bool asSink);
+
+ GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p)
+ : engine(eng), pred(pr), HasGeneratedNode(false), pp(p) {}
+
+public:
+ bool hasGeneratedNode() const { return HasGeneratedNode; }
+
+ WorkList &getWorkList() { return *engine.WList; }
+
+ ExplodedNode* getPredecessor() const { return pred; }
+
+ BlockCounter getBlockCounter() const {
+ return engine.WList->getBlockCounter();
+ }
+
+ const llvm::SmallVectorImpl<ExplodedNode*> &sinks() const {
+ return sinksGenerated;
+ }
+};
+
+template <typename PP>
+class GenericNodeBuilder : public GenericNodeBuilderImpl {
+public:
+ GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP &p)
+ : GenericNodeBuilderImpl(eng, pr, p) {}
+
+ ExplodedNode *generateNode(const GRState *state, ExplodedNode *pred,
+ PP programPoint, bool asSink) {
+ return generateNodeImpl(state, pred, programPoint, asSink);
+ }
+
+ const PP &getProgramPoint() const { return cast<PP>(pp); }
+};
+
class EndOfFunctionNodeBuilder {
CoreEngine &Eng;
const CFGBlock& B;
Modified: cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExprEngine.h?rev=123217&r1=123216&r2=123217&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExprEngine.h Tue Jan 11 00:37:47 2011
@@ -193,12 +193,10 @@
void ProcessTemporaryDtor(const CFGTemporaryDtor D,
StmtNodeBuilder &builder);
- /// processCFGBlockEntrance - Called by CoreEngine when start processing
- /// a CFGBlock. This method returns true if the analysis should continue
- /// exploring the given path, and false otherwise.
- bool processCFGBlockEntrance(const CFGBlock* B, const ExplodedNode *Pred,
- BlockCounter BC);
-
+ /// Called by CoreEngine when processing the entrance of a CFGBlock.
+ virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
+ GenericNodeBuilder<BlockEntrance> &nodeBuilder);
+
/// ProcessBranch - Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
void processBranch(const Stmt* Condition, const Stmt* Term,
Modified: cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/SubEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/SubEngine.h?rev=123217&r1=123216&r2=123217&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/SubEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/SubEngine.h Tue Jan 11 00:37:47 2011
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_GR_SUBENGINE_H
#define LLVM_CLANG_GR_SUBENGINE_H
+#include "clang/Analysis/ProgramPoint.h"
#include "clang/StaticAnalyzer/PathSensitive/SVals.h"
namespace clang {
@@ -23,8 +24,10 @@
class Stmt;
namespace ento {
-
+
+template <typename PP> class GenericNodeBuilder;
class AnalysisManager;
+class ExplodedNodeSet;
class ExplodedNode;
class GRState;
class GRStateManager;
@@ -52,12 +55,11 @@
/// nodes by processing the 'effects' of a block-level statement.
virtual void processCFGElement(const CFGElement E, StmtNodeBuilder& builder)=0;
- /// Called by CoreEngine when start processing
- /// a CFGBlock. This method returns true if the analysis should continue
- /// exploring the given path, and false otherwise.
- virtual bool processCFGBlockEntrance(const CFGBlock* B,
- const ExplodedNode *Pred,
- BlockCounter BC) = 0;
+ /// 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;
/// Called by CoreEngine. Used to generate successor
/// nodes by processing the 'effects' of a branch condition.
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp?rev=123217&r1=123216&r2=123217&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp Tue Jan 11 00:37:47 2011
@@ -1077,11 +1077,22 @@
// Block entrance. (Update counters).
//===----------------------------------------------------------------------===//
-bool ExprEngine::processCFGBlockEntrance(const CFGBlock* B,
- const ExplodedNode *Pred,
- BlockCounter BC) {
- return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(),
- B->getBlockID()) < AMgr.getMaxVisit();
+void ExprEngine::processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
+ GenericNodeBuilder<BlockEntrance> &nodeBuilder){
+
+ // FIXME: Refactor this into a checker.
+ const CFGBlock *block = nodeBuilder.getProgramPoint().getBlock();
+ ExplodedNode *pred = nodeBuilder.getPredecessor();
+
+ if (nodeBuilder.getBlockCounter().getNumVisited(
+ pred->getLocationContext()->getCurrentStackFrame(),
+ block->getBlockID()) >= AMgr.getMaxVisit()) {
+
+ static int tag = 0;
+ const BlockEntrance &BE = nodeBuilder.getProgramPoint();
+ BlockEntrance BE_tagged(BE.getBlock(), BE.getLocationContext(), &tag);
+ nodeBuilder.generateNode(pred->getState(), pred, BE_tagged, true);
+ }
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/StaticAnalyzer/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/CoreEngine.cpp?rev=123217&r1=123216&r2=123217&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/CoreEngine.cpp Tue Jan 11 00:37:47 2011
@@ -288,13 +288,29 @@
return;
}
- // FIXME: Should we allow processCFGBlockEntrance to also manipulate state?
-
- if (SubEng.processCFGBlockEntrance(Blk, Pred, WList->getBlockCounter()))
- generateNode(BlockEntrance(Blk, Pred->getLocationContext()),
- Pred->State, Pred);
+ // 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);
+
+ if (dstNodes.empty()) {
+ if (!nodeBuilder.hasGeneratedNode()) {
+ // Auto-generate a node and enqueue it to the worklist.
+ generateNode(BE, Pred->State, Pred);
+ }
+ }
else {
- blocksAborted.push_back(std::make_pair(L, Pred));
+ for (ExplodedNodeSet::iterator I = dstNodes.begin(), E = dstNodes.end();
+ I != E; ++I) {
+ WList->enqueue(*I);
+ }
+ }
+
+ for (llvm::SmallVectorImpl<ExplodedNode*>::const_iterator
+ I = nodeBuilder.sinks().begin(), E = nodeBuilder.sinks().end();
+ I != E; ++I) {
+ blocksAborted.push_back(std::make_pair(L, *I));
}
}
@@ -446,6 +462,27 @@
if (IsNew) WList->enqueue(Node);
}
+ExplodedNode *
+GenericNodeBuilderImpl::generateNodeImpl(const GRState *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;
+}
+
StmtNodeBuilder::StmtNodeBuilder(const CFGBlock* b, unsigned idx,
ExplodedNode* N, CoreEngine* e,
GRStateManager &mgr)
Modified: cfe/trunk/test/Analysis/retain-release-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release-region-store.m?rev=123217&r1=123216&r2=123217&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release-region-store.m (original)
+++ cfe/trunk/test/Analysis/retain-release-region-store.m Tue Jan 11 00:37:47 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-store=region -analyzer-max-loop 6 -verify %s
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from
More information about the cfe-commits
mailing list