forked from OSchip/llvm-project
-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:
parent
057094c6f6
commit
6f375e5604
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue