aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-09-13 09:13:49 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-09-13 09:13:49 +0000
commitdba3fb5413437dc613734fa4ffac892b11a37d25 (patch)
treef4c282a769444605f34ddc0feb062fced2cd9bc3 /lib/Analysis
parentc5d9a90b3a3c16324e0cceeccec3d2993888deb6 (diff)
Consolidate the logic for building a no-return CFG block into a single
location with a single comment rather than scattering it in three places. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139592 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/CFG.cpp44
1 files changed, 21 insertions, 23 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 69399f3bcd..12ff84417f 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -374,6 +374,7 @@ private:
void autoCreateBlock() { if (!Block) Block = createBlock(); }
CFGBlock *createBlock(bool add_successor = true);
+ CFGBlock *createNoReturnBlock();
CFGBlock *addStmt(Stmt *S) {
return Visit(S, AddStmtChoice::AlwaysAdd);
@@ -597,6 +598,15 @@ CFGBlock *CFGBuilder::createBlock(bool add_successor) {
return B;
}
+/// createNoReturnBlock - Used to create a block is a 'noreturn' point in the
+/// CFG. It is *not* connected to the current (global) successor, and instead
+/// directly tied to the exit block in order to be reachable.
+CFGBlock *CFGBuilder::createNoReturnBlock() {
+ CFGBlock *B = createBlock(false);
+ addSuccessor(B, &cfg->getExit());
+ return B;
+}
+
/// addInitializer - Add C++ base or member initializer element to CFG.
CFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) {
if (!BuildOpts.AddInitializers)
@@ -667,16 +677,10 @@ void CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B,
if (const ArrayType *AT = Context->getAsArrayType(Ty))
Ty = AT->getElementType();
const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
- if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr()) {
- Block = createBlock(/*add_successor=*/false);
- // Wire up this block directly to the exit block if we're in the
- // no-return case. We pruned any other successors because control flow
- // won't actually exit this block, but we want to be able to find all of
- // these entries in the CFG when doing analyses.
- addSuccessor(Block, &cfg->getExit());
- } else {
+ if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr())
+ Block = createNoReturnBlock();
+ else
autoCreateBlock();
- }
appendAutomaticObjDtor(Block, *I, S);
}
@@ -1207,13 +1211,13 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
return 0;
}
- Block = createBlock(!NoReturn);
+ if (NoReturn)
+ Block = createNoReturnBlock();
+ else
+ Block = createBlock();
+
appendStmt(Block, C);
- if (NoReturn) {
- // Wire this to the exit block directly.
- addSuccessor(Block, &cfg->getExit());
- }
if (AddEHEdge) {
// Add exceptional edges.
if (TryTerminatedBlock)
@@ -2884,16 +2888,10 @@ CFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors(
// a new block for the destructor which does not have as a successor
// anything built thus far. Control won't flow out of this block.
const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor();
- if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr()) {
- Block = createBlock(/*add_successor=*/false);
- // Wire up this block directly to the exit block if we're in the
- // no-return case. We pruned any other successors because control flow
- // won't actually exit this block, but we want to be able to find all of
- // these entries in the CFG when doing analyses.
- addSuccessor(Block, &cfg->getExit());
- } else {
+ if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr())
+ Block = createNoReturnBlock();
+ else
autoCreateBlock();
- }
appendTemporaryDtor(Block, E);
B = Block;