]> granicus.if.org Git - clang/commitdiff
Add a bit to the CFGBlock to track when it contains a no-return
authorChandler Carruth <chandlerc@gmail.com>
Tue, 13 Sep 2011 09:53:55 +0000 (09:53 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Tue, 13 Sep 2011 09:53:55 +0000 (09:53 +0000)
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

include/clang/Analysis/CFG.h
lib/Analysis/CFG.cpp

index f380012080d5e418621ca6db4b60f1a1e441beaf..f191c802818bebc7333e7891cd9b2f8c1d60e6ea 100644 (file)
@@ -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;
index 12ff84417fc451a81309072001a4f06364593a67..0775dcfb79edd5e723a2d4aee9cb217a2ccda294 100644 (file)
@@ -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;
 }