From 63d540399b189955e6caf5b8024981eedd215a07 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 5 Mar 2014 23:46:07 +0000 Subject: [PATCH] [-Wunreachable-code] generalize pruning out warning on trivial returns. 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 | 15 ++++++--------- test/Sema/warn-unreachable.c | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp index b772145456..7958840b89 100644 --- a/lib/Analysis/ReachableCode.cpp +++ b/lib/Analysis/ReachableCode.cpp @@ -291,12 +291,12 @@ static bool isEnumConstant(const Expr *Ex) { } static bool isTrivialExpression(const Expr *Ex) { + Ex = Ex->IgnoreParenCasts(); return isa(Ex) || isa(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(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; diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c index c877612c64..3c6d891613 100644 --- a/test/Sema/warn-unreachable.c +++ b/test/Sema/warn-unreachable.c @@ -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 }; -- 2.40.0