-Wunreachable-code: refine recognition of unreachable "sigil" to cope with implicit casts in C++.

Fixes <rdar://problem/16631033>.

llvm-svn: 206360
This commit is contained in:
Ted Kremenek 2014-04-16 07:26:09 +00:00
parent 057094c6f6
commit 6f375e5604
4 changed files with 63 additions and 1 deletions

View File

@ -699,6 +699,9 @@ public:
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts() LLVM_READONLY;
/// Ignore casts. Strip off any CastExprs, returning their operand.
Expr *IgnoreCasts() LLVM_READONLY;
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
/// any ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts() LLVM_READONLY;
@ -760,6 +763,11 @@ public:
const Expr *IgnoreParenCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenCasts();
}
/// Strip off casts, but keep parentheses.
const Expr *IgnoreCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreCasts();
}
const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
}

View File

@ -2400,6 +2400,27 @@ Expr *Expr::IgnoreParenCasts() {
}
}
Expr *Expr::IgnoreCasts() {
Expr *E = this;
while (true) {
if (CastExpr *P = dyn_cast<CastExpr>(E)) {
E = P->getSubExpr();
continue;
}
if (MaterializeTemporaryExpr *Materialize
= dyn_cast<MaterializeTemporaryExpr>(E)) {
E = Materialize->GetTemporaryExpr();
continue;
}
if (SubstNonTypeTemplateParmExpr *NTTP
= dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
}
return E;
}
}
/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
/// casts. This is intended purely as a temporary workaround for code
/// that hasn't yet been rewritten to do the right thing about those

View File

@ -139,6 +139,9 @@ static bool isConfigurationValue(const Stmt *S,
if (!S)
return false;
if (const Expr *Ex = dyn_cast<Expr>(S))
S = Ex->IgnoreCasts();
// Special case looking for the sigil '()' around an integer literal.
if (const ParenExpr *PE = dyn_cast<ParenExpr>(S))
if (!PE->getLocStart().isMacroID())
@ -146,7 +149,7 @@ static bool isConfigurationValue(const Stmt *S,
IncludeIntegers, true);
if (const Expr *Ex = dyn_cast<Expr>(S))
S = Ex->IgnoreParenCasts();
S = Ex->IgnoreCasts();
bool IgnoreYES_NO = false;

View File

@ -327,6 +327,36 @@ void test_with_paren_silencing(int x) {
calledFun();
}
void test_with_paren_silencing_impcast(int x) {
if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
if ((0)) calledFun(); // no-warning
if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
calledFun();
else
calledFun(); // expected-warning {{will never be executed}}
if ((1))
calledFun();
else
calledFun(); // no-warning
if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
calledFun(); // expected-warning {{code will never be executed}}
else
calledFun();
if ((!1))
calledFun(); // no-warning
else
calledFun();
if (!(1))
calledFun(); // no-warning
else
calledFun();
}
void tautological_compare(bool x, int y) {
if (x > 10) // expected-note {{silence}}
calledFun(); // expected-warning {{will never be executed}}