[cfe-commits] r93500 - /cfe/trunk/lib/Sema/SemaDecl.cpp

Mike Stump mrs at apple.com
Thu Jan 14 18:06:43 PST 2010


Author: mrs
Date: Thu Jan 14 20:06:42 2010
New Revision: 93500

URL: http://llvm.org/viewvc/llvm-project?rev=93500&view=rev
Log:
Refine unreachable warnings.  WIP.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=93500&r1=93499&r2=93500&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 14 20:06:42 2010
@@ -1328,6 +1328,66 @@
   }
 }
 
+static SourceLocation MarkLiveTop(CFGBlock *e, llvm::BitVector &live,
+                               SourceManager &SM) {
+  std::queue<CFGBlock*> workq;
+  // Prep work queue
+  workq.push(e);
+  SourceLocation top;
+  if (!e->empty())
+    top = e[0][0].getStmt()->getLocStart();
+  bool FromMainFile = false;
+  bool FromSystemHeader = false;
+  bool TopValid = false;
+  if (top.isValid()) {
+    FromMainFile = SM.isFromMainFile(top);
+    FromSystemHeader = SM.isInSystemHeader(top);
+    TopValid = true;
+  }
+  // Solve
+  while (!workq.empty()) {
+    CFGBlock *item = workq.front();
+    workq.pop();
+    SourceLocation c;
+    if (!item->empty())
+      c = item[0][0].getStmt()->getLocStart();
+    else if (item->getTerminator())
+      c = item->getTerminator()->getLocStart();
+    if (c.isValid()
+        && (!TopValid
+            || (SM.isFromMainFile(c) && !FromMainFile)
+            || (FromSystemHeader && !SM.isInSystemHeader(c))
+            || SM.isBeforeInTranslationUnit(c, top))) {
+      top = c;
+      FromMainFile = SM.isFromMainFile(top);
+      FromSystemHeader = SM.isInSystemHeader(top);
+    }
+    live.set(item->getBlockID());
+    for (CFGBlock::succ_iterator I=item->succ_begin(),
+           E=item->succ_end();
+         I != E;
+         ++I) {
+      if ((*I) && !live[(*I)->getBlockID()]) {
+        live.set((*I)->getBlockID());
+        workq.push(*I);
+      }
+    }
+  }
+  return top;
+}
+
+namespace {
+class LineCmp {
+  SourceManager &SM;
+public:
+  LineCmp(SourceManager &sm) : SM(sm) {
+  }
+  bool operator () (SourceLocation l1, SourceLocation l2) {
+    return l1 < l2;
+  }
+};
+}
+
 /// CheckUnreachable - Check for unreachable code.
 void Sema::CheckUnreachable(AnalysisContext &AC) {
   // We avoid checking when there are errors, as the CFG won't faithfully match
@@ -1345,15 +1405,38 @@
   // Mark all live things first.
   MarkLive(&cfg->getEntry(), live);
 
+  llvm::SmallVector<SourceLocation, 24> lines;
+  // First, give warnings for blocks with no predecessors, as they
+  // 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 (!b.empty())
-        Diag(b[0].getStmt()->getLocStart(), diag::warn_unreachable);
-      // Avoid excessive errors by marking everything reachable from here
-      MarkLive(&b, live);
+      if (b.pred_begin() == b.pred_end()) {
+        if (!b.empty())
+          lines.push_back(b[0].getStmt()->getLocStart());
+        else if (b.getTerminator())
+          lines.push_back(b.getTerminator()->getLocStart());
+        // Avoid excessive errors by marking everything reachable from here
+        MarkLive(&b, live);
+      }
     }
   }
+
+  // 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()])
+      // Avoid excessive errors by marking everything reachable from here
+      lines.push_back(MarkLiveTop(&b, live, Context.getSourceManager()));
+  }
+
+  std::sort(lines.begin(), lines.end(), LineCmp(Context.getSourceManager()));
+  for (llvm::SmallVector<SourceLocation, 24>::iterator I = lines.begin(),
+         E = lines.end();
+       I != E;
+       ++I)
+    if (I->isValid())
+      Diag(*I, diag::warn_unreachable);
 }
 
 /// CheckFallThrough - Check that we don't fall off the end of a





More information about the cfe-commits mailing list