From: Ted Kremenek Date: Sat, 8 Mar 2014 02:22:23 +0000 (+0000) Subject: [-Wunreachable-code] Handle 'return' with no argument dominated by 'noreturn' function. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42bbd736730bc774fb1ed0cde9140d18e7b4c4c7;p=clang [-Wunreachable-code] Handle 'return' with no argument dominated by 'noreturn' function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203333 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp index 47f8f2b90c..5d74156092 100644 --- a/lib/Analysis/ReachableCode.cpp +++ b/lib/Analysis/ReachableCode.cpp @@ -132,10 +132,8 @@ static bool isTrivialExpression(const Expr *Ex) { static bool isTrivialReturnOrDoWhile(const CFGBlock *B, const Stmt *S) { const Expr *Ex = dyn_cast(S); - if (!Ex) - return false; - if (!isTrivialExpression(Ex)) + if (Ex && !isTrivialExpression(Ex)) return false; // Check if the block ends with a do...while() and see if 'S' is the @@ -152,13 +150,20 @@ static bool isTrivialReturnOrDoWhile(const CFGBlock *B, const Stmt *S) { // 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 CS = I->getAs()) { if (const ReturnStmt *RS = dyn_cast(CS->getStmt())) { - const Expr *RE = RS->getRetValue(); - if (RE && stripExprSugar(RE->IgnoreParenCasts()) == Ex) + bool LookAtBody = false; + if (RS == S) + LookAtBody = true; + else { + const Expr *RE = RS->getRetValue(); + if (RE && stripExprSugar(RE->IgnoreParenCasts()) == Ex) + LookAtBody = true; + } + + if (LookAtBody) return bodyEndsWithNoReturn(*B->pred_begin()); } break; diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c index f32134bbdb..2334c37381 100644 --- a/test/Sema/warn-unreachable.c +++ b/test/Sema/warn-unreachable.c @@ -199,6 +199,11 @@ int trivial_dead_return() { return ((0)); // no-warning } +void trivial_dead_return_void() { + raze(); + return; // no-warning +} + MyEnum trival_dead_return_enum() { raze(); return Value1; // no-warning