[-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.

llvm-svn: 203029
This commit is contained in:
Ted Kremenek 2014-03-05 23:46:07 +00:00
parent 6766f8d23b
commit 0a69cabd35
2 changed files with 28 additions and 10 deletions

View 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;

View 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
};