diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-09-13 09:53:55 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-09-13 09:53:55 +0000 |
commit | 83754162f698a5dafad93fb89be0953651a604d0 (patch) | |
tree | dfbf9ce92f2d9a4af9ce57814202b594e5b7523c | |
parent | dba3fb5413437dc613734fa4ffac892b11a37d25 (diff) |
Add a bit to the CFGBlock to track when it contains a no-return
CFGElement. This will allow greatly simplifying the logic in
-Wreturn-type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139593 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/CFG.h | 16 | ||||
-rw-r--r-- | lib/Analysis/CFG.cpp | 1 |
2 files changed, 16 insertions, 1 deletions
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index f380012080..f191c80281 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -333,10 +333,21 @@ class CFGBlock { AdjacentBlocks Preds; AdjacentBlocks Succs; + /// NoReturn - This bit is set when the basic block contains a function call + /// or implicit destructor that is attributed as 'noreturn'. In that case, + /// control cannot technically ever proceed past this block. All such blocks + /// will have a single immediate successor: the exit block. This allows them + /// to be easily reached from the exit block and using this bit quickly + /// recognized without scanning the contents of the block. + /// + /// Optimization Note: This bit could be profitably folded with Terminator's + /// storage if the memory usage of CFGBlock becomes an issue. + unsigned HasNoReturnElement : 1; + public: explicit CFGBlock(unsigned blockid, BumpVectorContext &C) : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL), - BlockID(blockid), Preds(C, 1), Succs(C, 1) {} + BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false) {} ~CFGBlock() {} // Statement iterators @@ -458,6 +469,7 @@ public: void setTerminator(Stmt *Statement) { Terminator = Statement; } void setLabel(Stmt *Statement) { Label = Statement; } void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } + void setHasNoReturnElement() { HasNoReturnElement = true; } CFGTerminator getTerminator() { return Terminator; } const CFGTerminator getTerminator() const { return Terminator; } @@ -473,6 +485,8 @@ public: Stmt *getLabel() { return Label; } const Stmt *getLabel() const { return Label; } + bool hasNoReturnElement() const { return HasNoReturnElement; } + unsigned getBlockID() const { return BlockID; } void dump(const CFG *cfg, const LangOptions &LO) const; diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 12ff84417f..0775dcfb79 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -603,6 +603,7 @@ CFGBlock *CFGBuilder::createBlock(bool add_successor) { /// directly tied to the exit block in order to be reachable. CFGBlock *CFGBuilder::createNoReturnBlock() { CFGBlock *B = createBlock(false); + B->setHasNoReturnElement(); addSuccessor(B, &cfg->getExit()); return B; } |