diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-29 20:27:50 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-29 20:27:50 +0000 |
commit | 17f4dbde366b62e07b2a61b33f99310d9ede11c4 (patch) | |
tree | 2074e604bfcaaab695445ee5db47ca8bf8e1c36f | |
parent | 26edb59d979fc3e6b8fdc4c7f893802f9e33e8e7 (diff) | |
download | bcm5719-llvm-17f4dbde366b62e07b2a61b33f99310d9ede11c4.tar.gz bcm5719-llvm-17f4dbde366b62e07b2a61b33f99310d9ede11c4.zip |
"Refinement" of hack to bound loop-traversals: visit any block at a maximum of 3 times along a given path.
llvm-svn: 47766
-rw-r--r-- | clang/Analysis/GRCoreEngine.cpp | 8 | ||||
-rw-r--r-- | clang/Analysis/GRExprEngine.cpp | 60 | ||||
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h | 15 | ||||
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/GRExprEngine.h | 7 |
4 files changed, 40 insertions, 50 deletions
diff --git a/clang/Analysis/GRCoreEngine.cpp b/clang/Analysis/GRCoreEngine.cpp index 0e8be291863..4eb024f036d 100644 --- a/clang/Analysis/GRCoreEngine.cpp +++ b/clang/Analysis/GRCoreEngine.cpp @@ -136,11 +136,11 @@ void GRCoreEngineImpl::HandleBlockEdge(const BlockEdge& L, ExplodedNodeImpl* Pre // This path is done. Don't enqueue any more nodes. return; } + + // FIXME: Should we allow ProcessBlockEntrance to also manipulate state? - // FIXME: we will dispatch to a function that - // manipulates the state at the entrance to a block. - - GenerateNode(BlockEntrance(Blk), Pred->State, Pred); + if (ProcessBlockEntrance(Blk, Pred->State, WList->getBlockCounter())) + GenerateNode(BlockEntrance(Blk), Pred->State, Pred); } void GRCoreEngineImpl::HandleBlockEntrance(const BlockEntrance& L, diff --git a/clang/Analysis/GRExprEngine.cpp b/clang/Analysis/GRExprEngine.cpp index 74f3a9a48d7..2b94b4fafa9 100644 --- a/clang/Analysis/GRExprEngine.cpp +++ b/clang/Analysis/GRExprEngine.cpp @@ -147,6 +147,12 @@ ValueState* GRExprEngine::MarkBranch(ValueState* St, Stmt* Terminator, } } +bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, ValueState*, + GRBlockCounter BC) { + + return BC.getNumVisited(B->getBlockID()) < 3; +} + void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder) { @@ -156,15 +162,6 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, // Check for NULL conditions; e.g. "for(;;)" if (!Condition) { builder.markInfeasible(false); - - // Get the current block counter. - GRBlockCounter BC = builder.getBlockCounter(); - unsigned BlockID = builder.getTargetBlock(true)->getBlockID(); - unsigned NumVisited = BC.getNumVisited(BlockID); - - if (NumVisited < 1) builder.generateNode(PrevState, true); - else builder.markInfeasible(true); - return; } @@ -191,46 +188,25 @@ void GRExprEngine::ProcessBranch(Expr* Condition, Stmt* Term, return; } } - - // Get the current block counter. - GRBlockCounter BC = builder.getBlockCounter(); - unsigned BlockID = builder.getTargetBlock(true)->getBlockID(); - unsigned NumVisited = BC.getNumVisited(BlockID); - - if (isa<nonlval::ConcreteInt>(V) || - BC.getNumVisited(builder.getTargetBlock(true)->getBlockID()) < 1) { - // Process the true branch. - bool isFeasible = true; - - ValueState* St = Assume(PrevState, V, true, isFeasible); + // Process the true branch. - if (isFeasible) - builder.generateNode(MarkBranch(St, Term, true), true); - else - builder.markInfeasible(true); - } + bool isFeasible = true; + ValueState* St = Assume(PrevState, V, true, isFeasible); + + if (isFeasible) + builder.generateNode(MarkBranch(St, Term, true), true); else builder.markInfeasible(true); + + // Process the false branch. - BlockID = builder.getTargetBlock(false)->getBlockID(); - NumVisited = BC.getNumVisited(BlockID); + isFeasible = false; + St = Assume(PrevState, V, false, isFeasible); - if (isa<nonlval::ConcreteInt>(V) || - BC.getNumVisited(builder.getTargetBlock(false)->getBlockID()) < 1) { - - // Process the false branch. - - bool isFeasible = false; - - ValueState* St = Assume(PrevState, V, false, isFeasible); - - if (isFeasible) - builder.generateNode(MarkBranch(St, Term, false), false); - else - builder.markInfeasible(false); - } + if (isFeasible) + builder.generateNode(MarkBranch(St, Term, false), false); else builder.markInfeasible(false); } diff --git a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h index d3325b1b128..93f30c2027f 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -86,11 +86,14 @@ protected: ExplodedNodeImpl* Pred); virtual void* ProcessEOP(CFGBlock* Blk, void* State) = 0; + + virtual bool ProcessBlockEntrance(CFGBlock* Blk, void* State, + GRBlockCounter BC) = 0; - virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0; + virtual void ProcessStmt(Stmt* S, GRStmtNodeBuilderImpl& Builder) = 0; - virtual void ProcessBranch(Expr* Condition, Stmt* Terminator, - GRBranchNodeBuilderImpl& Builder) = 0; + virtual void ProcessBranch(Expr* Condition, Stmt* Terminator, + GRBranchNodeBuilderImpl& Builder) = 0; virtual void ProcessIndirectGoto(GRIndirectGotoNodeBuilderImpl& Builder) = 0; @@ -434,6 +437,12 @@ protected: GRStmtNodeBuilder<CHECKER> Builder(BuilderImpl); Checker->ProcessStmt(S, Builder); } + + virtual bool ProcessBlockEntrance(CFGBlock* Blk, void* State, + GRBlockCounter BC) { + return Checker->ProcessBlockEntrance(Blk, + GRTrait<StateTy>::toState(State), BC); + } virtual void ProcessBranch(Expr* Condition, Stmt* Terminator, GRBranchNodeBuilderImpl& BuilderImpl) { diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index efccf02f6e8..b4751666b2a 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -211,9 +211,14 @@ public: undef_result_iterator undef_results_end() { return UndefResults.end(); } /// ProcessStmt - Called by GRCoreEngine. Used to generate new successor - /// nodes by processing the 'effects' of a block-level statement. + /// nodes by processing the 'effects' of a block-level statement. void ProcessStmt(Stmt* S, StmtNodeBuilder& builder); + /// ProcessBlockEntrance - Called by GRCoreEngine when start processing + /// a CFGBlock. This method returns true if the analysis should continue + /// exploring the given path, and false otherwise. + bool ProcessBlockEntrance(CFGBlock* B, ValueState* St, GRBlockCounter BC); + /// ProcessBranch - Called by GRCoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. void ProcessBranch(Expr* Condition, Stmt* Term, BranchNodeBuilder& builder); |