зеркало из https://github.com/microsoft/clang-1.git
Removed implicit transitions to a "BlockExit" location; we now handle
the end of the block by processing empty blocks (at BlockEntrance) or when we have just processed the last statement in a block (at PostStmt). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45991 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
3bf49e3fa8
Коммит
425c08c53c
|
@ -88,7 +88,7 @@ bool GREngineImpl::ExecuteWorkList(unsigned Steps) {
|
|||
break;
|
||||
|
||||
case ProgramPoint::BlockExitKind:
|
||||
HandleBlockExit(cast<BlockExit>(Node->getLocation()), Node);
|
||||
assert (false && "BlockExit location never occur in forward analysis.");
|
||||
break;
|
||||
|
||||
case ProgramPoint::PostStmtKind:
|
||||
|
@ -127,10 +127,7 @@ void GREngineImpl::HandleBlockEdge(const BlockEdge& L, ExplodedNodeImpl* Pred) {
|
|||
// FIXME: we will dispatch to a function that
|
||||
// manipulates the state at the entrance to a block.
|
||||
|
||||
if (!Blk->empty())
|
||||
GenerateNode(BlockEntrance(Blk), Pred->State, Pred);
|
||||
else
|
||||
GenerateNode(BlockExit(Blk), Pred->State, Pred);
|
||||
GenerateNode(BlockEntrance(Blk), Pred->State, Pred);
|
||||
}
|
||||
|
||||
void GREngineImpl::HandleBlockEntrance(const BlockEntrance& L,
|
||||
|
@ -140,14 +137,12 @@ void GREngineImpl::HandleBlockEntrance(const BlockEntrance& L,
|
|||
GRNodeBuilderImpl Builder(L.getBlock(), 0, Pred, this);
|
||||
ProcessStmt(S, Builder);
|
||||
}
|
||||
else
|
||||
GenerateNode(BlockExit(L.getBlock()), Pred->State, Pred);
|
||||
else
|
||||
HandleBlockExit(L.getBlock(), Pred);
|
||||
}
|
||||
|
||||
|
||||
void GREngineImpl::HandleBlockExit(const BlockExit& L, ExplodedNodeImpl* Pred) {
|
||||
|
||||
CFGBlock* B = L.getBlock();
|
||||
void GREngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) {
|
||||
|
||||
if (Stmt* Terminator = B->getTerminator())
|
||||
ProcessTerminator(Terminator, B, Pred);
|
||||
|
@ -164,12 +159,8 @@ void GREngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B,
|
|||
|
||||
assert (!B->empty());
|
||||
|
||||
if (StmtIdx == B->size()) {
|
||||
// FIXME: This is essentially an epsilon-transition. Do we need it?
|
||||
// It does simplify the logic, and it is also another point
|
||||
// were we could introduce a dispatch to the client.
|
||||
GenerateNode(BlockExit(B), Pred->State, Pred);
|
||||
}
|
||||
if (StmtIdx == B->size())
|
||||
HandleBlockExit(B, Pred);
|
||||
else {
|
||||
GRNodeBuilderImpl Builder(B, StmtIdx, Pred, this);
|
||||
ProcessStmt(L.getStmt(), Builder);
|
||||
|
|
|
@ -60,7 +60,7 @@ protected:
|
|||
|
||||
void HandleBlockEdge(const BlockEdge& E, ExplodedNodeImpl* Pred);
|
||||
void HandleBlockEntrance(const BlockEntrance& E, ExplodedNodeImpl* Pred);
|
||||
void HandleBlockExit(const BlockExit& E, ExplodedNodeImpl* Pred);
|
||||
void HandleBlockExit(CFGBlock* B, ExplodedNodeImpl* Pred);
|
||||
void HandlePostStmt(const PostStmt& S, CFGBlock* B,
|
||||
unsigned StmtIdx, ExplodedNodeImpl *Pred);
|
||||
|
||||
|
@ -195,7 +195,9 @@ public:
|
|||
/// a DFS exploration of the exploded graph.
|
||||
GREngine(CFG& Cfg)
|
||||
: GREngineImpl(cfg, new GraphTy(), GRWorkList::MakeDFS()),
|
||||
Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {}
|
||||
Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {
|
||||
Checker->Initialize(cfg);
|
||||
}
|
||||
|
||||
/// Construct a GREngine object to analyze the provided CFG and to
|
||||
/// use the provided worklist object to execute the worklist algorithm.
|
||||
|
|
Загрузка…
Ссылка в новой задаче