[cfe-commits] r93574 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/Sema/warn-unreachable.c

Mike Stump mrs at apple.com
Fri Jan 15 15:17:13 PST 2010


Author: mrs
Date: Fri Jan 15 17:17:13 2010
New Revision: 93574

URL: http://llvm.org/viewvc/llvm-project?rev=93574&view=rev
Log:
Refine location reporting for unreachable code warnings for comma expressions.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/warn-unreachable.c

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jan 15 17:17:13 2010
@@ -1328,14 +1328,47 @@
   }
 }
 
+static SourceLocation GetUnreachableLoc(CFGBlock &b) {
+  Stmt *S;
+  if (!b.empty())
+    S = b[0].getStmt();
+  else if (b.getTerminator())
+    S = b.getTerminator();
+  else
+    return SourceLocation();
+
+  switch (S->getStmtClass()) {
+  case Expr::BinaryOperatorClass: {
+    BinaryOperator *Op = cast<BinaryOperator>(S);
+    if (Op->getOpcode() == BinaryOperator::Comma) {
+      if (b.size() < 2) {
+        CFGBlock *n = &b;
+        while (1) {
+          if (n->getTerminator())
+            return n->getTerminator()->getLocStart();
+          if (n->succ_size() != 1)
+            return SourceLocation();
+          n = n[0].succ_begin()[0];
+          if (n->pred_size() != 1)
+            return SourceLocation();
+          if (!n->empty())
+            return n[0][0].getStmt()->getLocStart();
+        }
+      }
+      return b[1].getStmt()->getLocStart();
+    }
+  }
+  default: ;
+  }
+  return S->getLocStart();
+}
+
 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();
+  SourceLocation top = GetUnreachableLoc(*e);
   bool FromMainFile = false;
   bool FromSystemHeader = false;
   bool TopValid = false;
@@ -1348,11 +1381,7 @@
   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();
+    SourceLocation c = GetUnreachableLoc(*item);
     if (c.isValid()
         && (!TopValid
             || (SM.isFromMainFile(c) && !FromMainFile)
@@ -1412,10 +1441,14 @@
     CFGBlock &b = **I;
     if (!live[b.getBlockID()]) {
       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());
+        SourceLocation c = GetUnreachableLoc(b);
+        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());
+          continue;
+        }
+        lines.push_back(c);
         // Avoid excessive errors by marking everything reachable from here
         MarkLive(&b, live);
       }

Modified: cfe/trunk/test/Sema/warn-unreachable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-unreachable.c?rev=93574&r1=93573&r2=93574&view=diff

==============================================================================
--- cfe/trunk/test/Sema/warn-unreachable.c (original)
+++ cfe/trunk/test/Sema/warn-unreachable.c Fri Jan 15 17:17:13 2010
@@ -1,5 +1,9 @@
 // RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code
 
+int halt() __attribute__((noreturn));
+int live();
+int dead();
+
 void test1() {
   goto c;
   d:
@@ -18,3 +22,55 @@
   goto d;
   f: ;
 }
+
+void test2() {
+  switch (live()) {
+  case 1:
+    halt(),
+      dead();   // expected-warning {{will never be executed}}
+
+  case 2:
+    live(),
+      halt(),
+      dead();   // expected-warning {{will never be executed}}
+
+  case 3:
+    live(),
+      halt();
+    dead();     // expected-warning {{will never be executed}}
+
+  case 4:
+  a4:
+    live(),
+      halt();
+    goto a4;    // expected-warning {{will never be executed}}
+
+  case 5:
+    goto a5;
+  c5:
+    dead();     // expected-warning {{will never be executed}}
+    goto b5;
+  a5:
+    live(),
+      halt();
+  b5:
+    goto c5;
+
+  case 6:
+    if (live())
+      goto e6;
+    live(),
+      halt();
+  d6:
+    dead();     // expected-warning {{will never be executed}}
+    goto b6;
+  c6:
+    dead();
+    goto b6;
+  e6:
+    live(),
+      halt();
+  b6:
+    goto c6;
+  }
+}





More information about the cfe-commits mailing list