[cfe-commits] r96872 - in /cfe/trunk/lib: Analysis/CMakeLists.txt Analysis/ReachableCode.cpp Sema/SemaChecking.cpp

Ted Kremenek kremenek at apple.com
Mon Feb 22 18:39:17 PST 2010


Author: kremenek
Date: Mon Feb 22 20:39:16 2010
New Revision: 96872

URL: http://llvm.org/viewvc/llvm-project?rev=96872&view=rev
Log:
Start moving some of the logic for the unreachable code analysis out of libSema
and into libAnalysis.

Added:
    cfe/trunk/lib/Analysis/ReachableCode.cpp
Modified:
    cfe/trunk/lib/Analysis/CMakeLists.txt
    cfe/trunk/lib/Sema/SemaChecking.cpp

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=96872&r1=96871&r2=96872&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Mon Feb 22 20:39:16 2010
@@ -5,6 +5,7 @@
   CFG.cpp
   LiveVariables.cpp
   PrintfFormatString.cpp
+  ReachableCode.cpp
   UninitializedValues.cpp
   )
 

Added: cfe/trunk/lib/Analysis/ReachableCode.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ReachableCode.cpp?rev=96872&view=auto
==============================================================================
--- cfe/trunk/lib/Analysis/ReachableCode.cpp (added)
+++ cfe/trunk/lib/Analysis/ReachableCode.cpp Mon Feb 22 20:39:16 2010
@@ -0,0 +1,52 @@
+//=- ReachableCodePathInsensitive.cpp ---------------------------*- C++ --*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a flow-sensitive, path-insensitive analysis of
+// determining reachable blocks within a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "clang/Analysis/Analyses/ReachableCode.h"
+#include "clang/Analysis/CFG.h"
+
+using namespace clang;
+
+/// ScanReachableFromBlock - Mark all blocks reachable from Start.
+/// Returns the total number of blocks that were marked reachable.
+unsigned clang::ScanReachableFromBlock(const CFGBlock &Start,
+                                       llvm::BitVector &Reachable) {
+  unsigned count = 0;
+  llvm::SmallVector<const CFGBlock*, 12> WL;
+  
+  // Prep work queue
+  Reachable.set(Start.getBlockID());
+  ++count;
+  WL.push_back(&Start);
+  
+  // Find the reachable blocks from 'Start'.
+  while (!WL.empty()) {
+    const CFGBlock *item = WL.back();
+    WL.pop_back();
+    
+    // Look at the successors and mark then reachable.
+    for (CFGBlock::const_succ_iterator I=item->succ_begin(), E=item->succ_end();
+         I != E; ++I)
+      if (const CFGBlock *B = *I) {
+        unsigned blockID = B->getBlockID();
+        if (!Reachable[blockID]) {
+          Reachable.set(blockID);
+          ++count;
+          WL.push_back(B);
+        }
+      }
+  }
+  return count;
+}

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=96872&r1=96871&r2=96872&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Feb 22 20:39:16 2010
@@ -13,8 +13,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
-#include "clang/Analysis/CFG.h"
 #include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/Analyses/ReachableCode.h"
 #include "clang/Analysis/Analyses/PrintfFormatString.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -2104,37 +2105,6 @@
   return;
 }
 
-// MarkReachable - Mark all the blocks reachable from Start as live. 
-// Returns the total number of blocks that were marked reachable.
-static unsigned MarkReachable(CFGBlock &Start, llvm::BitVector &live) {
-  unsigned count = 0;
-  llvm::SmallVector<CFGBlock*, 12> WL;
-
-  // Prep work queue
-  live.set(Start.getBlockID());
-  ++count;
-  WL.push_back(&Start);
-  
-  // Find the reachable blocks from 'Start'.
-  while (!WL.empty()) {
-    CFGBlock *item = WL.back();
-    WL.pop_back();
-    
-    // Look at the successors and mark then reachable.
-    for (CFGBlock::succ_iterator I=item->succ_begin(), E=item->succ_end();
-         I != E; ++I)
-      if (CFGBlock *B = *I) {
-        unsigned blockID = B->getBlockID();
-        if (!live[blockID]) {
-          live.set(blockID);
-          ++count;
-          WL.push_back(B);
-        }
-      }
-  }
-  return count;
-}
-
 static SourceLocation GetUnreachableLoc(CFGBlock &b, SourceRange &R1,
                                         SourceRange &R2) {
   Stmt *S;
@@ -2281,7 +2251,6 @@
 
 /// CheckUnreachable - Check for unreachable code.
 void Sema::CheckUnreachable(AnalysisContext &AC) {
-  unsigned count;
   // We avoid checking when there are errors, as the CFG won't faithfully match
   // the user's code.
   if (getDiagnostics().hasErrorOccurred() ||
@@ -2293,11 +2262,11 @@
     return;
 
   // Mark all live things first.
-  llvm::BitVector live(cfg->getNumBlockIDs());
-  count = MarkReachable(cfg->getEntry(), live);
+  llvm::BitVector reachable(cfg->getNumBlockIDs());
+  unsigned numReachable = ScanReachableFromBlock(cfg->getEntry(), reachable);
 
   // If there are no dead blocks, we're done.
-  if (count == cfg->getNumBlockIDs())
+  if (numReachable == cfg->getNumBlockIDs())
     return;
 
   SourceRange R1, R2;
@@ -2308,37 +2277,37 @@
   // can't be part of a loop.
   for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
     CFGBlock &b = **I;
-    if (!live[b.getBlockID()]) {
+    if (!reachable[b.getBlockID()]) {
       if (b.pred_begin() == b.pred_end()) {
         if (!AddEHEdges && b.getTerminator()
             && isa<CXXTryStmt>(b.getTerminator())) {
           // When not adding EH edges from calls, catch clauses
           // can otherwise seem dead.  Avoid noting them as dead.
-          count += MarkReachable(b, live);
+          numReachable += ScanReachableFromBlock(b, reachable);
           continue;
         }
         SourceLocation c = GetUnreachableLoc(b, R1, R2);
         if (!c.isValid()) {
           // Blocks without a location can't produce a warning, so don't mark
           // reachable blocks from here as live.
-          live.set(b.getBlockID());
-          ++count;
+          reachable.set(b.getBlockID());
+          ++numReachable;
           continue;
         }
         lines.push_back(ErrLoc(c, R1, R2));
         // Avoid excessive errors by marking everything reachable from here
-        count += MarkReachable(b, live);
+        numReachable += ScanReachableFromBlock(b, reachable);
       }
     }
   }
 
-  if (count < cfg->getNumBlockIDs()) {
+  if (numReachable < cfg->getNumBlockIDs()) {
     // And then give warnings for the tops of loops.
     for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
       CFGBlock &b = **I;
-      if (!live[b.getBlockID()])
+      if (!reachable[b.getBlockID()])
         // Avoid excessive errors by marking everything reachable from here
-        lines.push_back(ErrLoc(MarkLiveTop(&b, live,
+        lines.push_back(ErrLoc(MarkLiveTop(&b, reachable,
                                            Context.getSourceManager()),
                                SourceRange(), SourceRange()));
     }
@@ -2370,7 +2339,7 @@
   // confuse us, so we mark all live things first.
   std::queue<CFGBlock*> workq;
   llvm::BitVector live(cfg->getNumBlockIDs());
-  unsigned count = MarkReachable(cfg->getEntry(), live);
+  unsigned count = ScanReachableFromBlock(cfg->getEntry(), live);
 
   bool AddEHEdges = AC.getAddEHEdges();
   if (!AddEHEdges && count != cfg->getNumBlockIDs())
@@ -2384,7 +2353,7 @@
           if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
             // When not adding EH edges from calls, catch clauses
             // can otherwise seem dead.  Avoid noting them as dead.
-            count += MarkReachable(b, live);
+            count += ScanReachableFromBlock(b, live);
           continue;
         }
       }





More information about the cfe-commits mailing list