summaryrefslogtreecommitdiffstats
path: root/clang/Analysis/GRCoreEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-02-13 23:08:21 +0000
committerTed Kremenek <kremenek@apple.com>2008-02-13 23:08:21 +0000
commit80ebc1d1c95704b0ff0386b3a3cbc8b3ff960654 (patch)
tree9a949687f10ed70c7eafc36db7678a51f98380e8 /clang/Analysis/GRCoreEngine.cpp
parent9ca025f1dc2f7e32ddc4ba8fc24c40f221f79366 (diff)
downloadbcm5719-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.cpp55
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;
+}
OpenPOWER on IntegriCloud