diff options
| author | Ted Kremenek <kremenek@apple.com> | 2008-02-13 23:08:21 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2008-02-13 23:08:21 +0000 |
| commit | 80ebc1d1c95704b0ff0386b3a3cbc8b3ff960654 (patch) | |
| tree | 9a949687f10ed70c7eafc36db7678a51f98380e8 /clang/Analysis/GRCoreEngine.cpp | |
| parent | 9ca025f1dc2f7e32ddc4ba8fc24c40f221f79366 (diff) | |
| download | bcm5719-llvm-80ebc1d1c95704b0ff0386b3a3cbc8b3ff960654.tar.gz bcm5719-llvm-80ebc1d1c95704b0ff0386b3a3cbc8b3ff960654.zip | |
Added support to GRCoreEngine/GRExprEngine for processing control-flow
from switch...case...default statements.
llvm-svn: 47100
Diffstat (limited to 'clang/Analysis/GRCoreEngine.cpp')
| -rw-r--r-- | clang/Analysis/GRCoreEngine.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/Analysis/GRCoreEngine.cpp b/clang/Analysis/GRCoreEngine.cpp index 5a4ae81ecdc..0e8be291863 100644 --- a/clang/Analysis/GRCoreEngine.cpp +++ b/clang/Analysis/GRCoreEngine.cpp @@ -213,6 +213,15 @@ void GRCoreEngineImpl::HandleBlockExit(CFGBlock * B, ExplodedNodeImpl* Pred) { return; } + case Stmt::SwitchStmtClass: { + GRSwitchNodeBuilderImpl builder(Pred, B, + cast<SwitchStmt>(Term)->getCond(), + this); + + ProcessSwitch(builder); + return; + } + case Stmt::WhileStmtClass: HandleBranch(cast<WhileStmt>(Term)->getCond(), Term, B, Pred); return; @@ -386,3 +395,49 @@ GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I, return NULL; } + + +ExplodedNodeImpl* +GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, void* St) { + + bool IsNew; + + ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src, + I.getBlock()), + St, &IsNew); + Succ->addPredecessor(Pred); + + if (IsNew) { + Eng.WList->Enqueue(Succ); + return Succ; + } + + return NULL; +} + + +ExplodedNodeImpl* +GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(void* St, bool isSink) { + + // Get the block for the default case. + assert (Src->succ_rbegin() != Src->succ_rend()); + CFGBlock* DefaultBlock = *Src->succ_rbegin(); + + bool IsNew; + + ExplodedNodeImpl* Succ = Eng.G->getNodeImpl(BlockEdge(Eng.getCFG(), Src, + DefaultBlock), + St, &IsNew); + Succ->addPredecessor(Pred); + + if (IsNew) { + if (isSink) + Succ->markAsSink(); + else + Eng.WList->Enqueue(Succ); + + return Succ; + } + + return NULL; +} |

