]> granicus.if.org Git - clang/commitdiff
[-Wunreachable-code] generalize pruning out warning on trivial returns.
authorTed Kremenek <kremenek@apple.com>
Wed, 5 Mar 2014 23:46:07 +0000 (23:46 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 5 Mar 2014 23:46:07 +0000 (23:46 +0000)
Previously we only pruned dead returns preceded by a call to a
'noreturn' function.  After looking at the results of the LLVM codebase,
there are many others that should be pruned as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203029 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ReachableCode.cpp
test/Sema/warn-unreachable.c

index b772145456ee723dede38fc284d9708eb4c64b0e..7958840b89d0c638bccb042c7037c13f9a308eeb 100644 (file)
@@ -291,12 +291,12 @@ static bool isEnumConstant(const Expr *Ex) {
 }
 
 static bool isTrivialExpression(const Expr *Ex) {
+  Ex = Ex->IgnoreParenCasts();
   return isa<IntegerLiteral>(Ex) || isa<StringLiteral>(Ex) ||
          isEnumConstant(Ex);
 }
 
-static bool isTrivialReturnPrecededByNoReturn(const CFGBlock *B,
-                                              const Stmt *S) {
+static bool isTrivialReturn(const CFGBlock *B, const Stmt *S) {
   if (B->pred_empty())
     return false;
 
@@ -304,8 +304,6 @@ static bool isTrivialReturnPrecededByNoReturn(const CFGBlock *B,
   if (!Ex)
     return false;
 
-  Ex = Ex->IgnoreParenCasts();
-
   if (!isTrivialExpression(Ex))
     return false;
 
@@ -319,14 +317,13 @@ static bool isTrivialReturnPrecededByNoReturn(const CFGBlock *B,
       if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(CS->getStmt())) {
         const Expr *RE = RS->getRetValue();
         if (RE && RE->IgnoreParenCasts() == Ex)
-          break;
+          return true;
       }
-      return false;
+      break;
     }
   }
 
-  assert(B->pred_size() == 1);
-  return bodyEndsWithNoReturn(*B->pred_begin());
+  return false;
 }
 
 void DeadCodeScan::reportDeadCode(const CFGBlock *B,
@@ -339,7 +336,7 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
     return;
 
   // Suppress trivial 'return' statements that are dead.
-  if (isTrivialReturnPrecededByNoReturn(B, S))
+  if (isTrivialReturn(B, S))
     return;
 
   SourceRange R1, R2;
index c877612c649823db5720cea7b443dc62de6b6d65..3c6d891613abed46e83363abd2d4e2fec1750653 100644 (file)
@@ -204,6 +204,27 @@ MyEnum trival_dead_return_enum() {
   return Value1; // no-warning
 }
 
+MyEnum trivial_dead_return_enum_2(int x) {
+  switch (x) {
+    case 1: return 1;
+    case 2: return 2;
+    case 3: return 3;
+  }
+
+  return 2; // no-warning
+}
+
+MyEnum nontrivial_dead_return_enum_2(int x) {
+  switch (x) {
+    case 1: return 1;
+    case 2: return 2;
+    case 3: return 3;
+    default: return 4;
+  }
+
+  return calledFun(); // expected-warning {{will never be executed}}
+}
+
 // Test unreachable code depending on configuration values
 #define CONFIG_CONSTANT 1
 int test_config_constant(int x) {
@@ -235,7 +256,7 @@ int sizeof_int() {
   return 2; // no-warning
 }
 
-enum MyEnum {
+enum MyEnum2 {
   ME_A = CONFIG_CONSTANT,
   ME_B = 1
 };