r202352 - [-Wunreachable-code] Don't warn about trivially unreachable return statements preceded by 'noreturn' functions.

Ted Kremenek kremenek at apple.com
Wed Feb 26 22:32:32 PST 2014


Author: kremenek
Date: Thu Feb 27 00:32:32 2014
New Revision: 202352

URL: http://llvm.org/viewvc/llvm-project?rev=202352&view=rev
Log:
[-Wunreachable-code] Don't warn about trivially unreachable return statements preceded by 'noreturn' functions.

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

Modified: cfe/trunk/lib/Analysis/ReachableCode.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ReachableCode.cpp?rev=202352&r1=202351&r2=202352&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ReachableCode.cpp (original)
+++ cfe/trunk/lib/Analysis/ReachableCode.cpp Thu Feb 27 00:32:32 2014
@@ -262,6 +262,12 @@ static bool bodyEndsWithNoReturn(const C
   return false;
 }
 
+static bool bodyEndsWithNoReturn(const CFGBlock::AdjacentBlock &AB) {
+  const CFGBlock *Pred = AB.getPossiblyUnreachableBlock();
+  assert(!AB.isReachable() && Pred);
+  return bodyEndsWithNoReturn(Pred);
+}
+
 static bool isBreakPrecededByNoReturn(const CFGBlock *B,
                                       const Stmt *S) {
   if (!isa<BreakStmt>(S) || B->pred_empty())
@@ -269,10 +275,53 @@ static bool isBreakPrecededByNoReturn(co
 
   assert(B->empty());
   assert(B->pred_size() == 1);
-  const CFGBlock::AdjacentBlock &AB = *B->pred_begin();
-  const CFGBlock *Pred = AB.getPossiblyUnreachableBlock();
-  assert(!AB.isReachable() && Pred);
-  return bodyEndsWithNoReturn(Pred);
+  return bodyEndsWithNoReturn(*B->pred_begin());
+}
+
+static bool isEnumConstant(const Expr *Ex) {
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex);
+  if (!DR)
+    return false;
+  return isa<EnumConstantDecl>(DR->getDecl());
+}
+
+static bool isTrivialExpression(const Expr *Ex) {
+  return isa<IntegerLiteral>(Ex) || isa<StringLiteral>(Ex) ||
+         isEnumConstant(Ex);
+}
+
+static bool isTrivialReturnPrecededByNoReturn(const CFGBlock *B,
+                                              const Stmt *S) {
+  if (B->pred_empty())
+    return false;
+
+  const Expr *Ex = dyn_cast<Expr>(S);
+  if (!Ex)
+    return false;
+
+  Ex = Ex->IgnoreParenCasts();
+
+  if (!isTrivialExpression(Ex))
+    return false;
+
+  // Look to see if the block ends with a 'return', and see if 'S'
+  // is a substatement.  The 'return' may not be the last element in
+  // the block because of destructors.
+  assert(!B->empty());
+  for (CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
+       I != E; ++I) {
+    if (Optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
+      if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(CS->getStmt())) {
+        const Expr *RE = RS->getRetValue();
+        if (RE && RE->IgnoreParenCasts() == Ex)
+          break;
+      }
+      return false;
+    }
+  }
+
+  assert(B->pred_size() == 1);
+  return bodyEndsWithNoReturn(*B->pred_begin());
 }
 
 void DeadCodeScan::reportDeadCode(const CFGBlock *B,
@@ -284,6 +333,10 @@ void DeadCodeScan::reportDeadCode(const
   if (isBreakPrecededByNoReturn(B, S))
     return;
 
+  // Suppress trivial 'return' statements that are dead.
+  if (isTrivialReturnPrecededByNoReturn(B, S))
+    return;
+
   // Was this an unreachable 'default' case?  Such cases are covered
   // by -Wcovered-switch-default, if the user so desires.
   const Stmt *Label = B->getLabel();

Modified: cfe/trunk/test/Sema/warn-unreachable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-unreachable.c?rev=202352&r1=202351&r2=202352&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-unreachable.c (original)
+++ cfe/trunk/test/Sema/warn-unreachable.c Thu Feb 27 00:32:32 2014
@@ -187,3 +187,16 @@ void unreachable_in_default(MyEnum e) {
   }
 }
 
+// Don't warn about trivial dead returns.
+int trivial_dead_return() {
+  raze();
+  // Use the '()' to test that we unwrap such stuff
+  // when looking for dead code.
+  return ((0)); // no-warning
+}
+
+MyEnum trival_dead_return_enum() {
+  raze();
+  return Value1; // no-warning
+}
+





More information about the cfe-commits mailing list