}
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;
if (!Ex)
return false;
- Ex = Ex->IgnoreParenCasts();
-
if (!isTrivialExpression(Ex))
return false;
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,
return;
// Suppress trivial 'return' statements that are dead.
- if (isTrivialReturnPrecededByNoReturn(B, S))
+ if (isTrivialReturn(B, S))
return;
SourceRange R1, R2;
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) {
return 2; // no-warning
}
-enum MyEnum {
+enum MyEnum2 {
ME_A = CONFIG_CONSTANT,
ME_B = 1
};