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.
|
/// or CastExprs, returning their operand.
|
||||||
Expr *IgnoreParenCasts() LLVM_READONLY;
|
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
|
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
|
||||||
/// any ParenExpr or ImplicitCastExprs, returning their operand.
|
/// any ParenExpr or ImplicitCastExprs, returning their operand.
|
||||||
Expr *IgnoreParenImpCasts() LLVM_READONLY;
|
Expr *IgnoreParenImpCasts() LLVM_READONLY;
|
||||||
|
@ -760,6 +763,11 @@ public:
|
||||||
const Expr *IgnoreParenCasts() const LLVM_READONLY {
|
const Expr *IgnoreParenCasts() const LLVM_READONLY {
|
||||||
return const_cast<Expr*>(this)->IgnoreParenCasts();
|
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 {
|
const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
|
||||||
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
|
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
|
/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
|
||||||
/// casts. This is intended purely as a temporary workaround for code
|
/// casts. This is intended purely as a temporary workaround for code
|
||||||
/// that hasn't yet been rewritten to do the right thing about those
|
/// 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)
|
if (!S)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (const Expr *Ex = dyn_cast<Expr>(S))
|
||||||
|
S = Ex->IgnoreCasts();
|
||||||
|
|
||||||
// Special case looking for the sigil '()' around an integer literal.
|
// Special case looking for the sigil '()' around an integer literal.
|
||||||
if (const ParenExpr *PE = dyn_cast<ParenExpr>(S))
|
if (const ParenExpr *PE = dyn_cast<ParenExpr>(S))
|
||||||
if (!PE->getLocStart().isMacroID())
|
if (!PE->getLocStart().isMacroID())
|
||||||
|
@ -146,7 +149,7 @@ static bool isConfigurationValue(const Stmt *S,
|
||||||
IncludeIntegers, true);
|
IncludeIntegers, true);
|
||||||
|
|
||||||
if (const Expr *Ex = dyn_cast<Expr>(S))
|
if (const Expr *Ex = dyn_cast<Expr>(S))
|
||||||
S = Ex->IgnoreParenCasts();
|
S = Ex->IgnoreCasts();
|
||||||
|
|
||||||
bool IgnoreYES_NO = false;
|
bool IgnoreYES_NO = false;
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,36 @@ void test_with_paren_silencing(int x) {
|
||||||
calledFun();
|
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) {
|
void tautological_compare(bool x, int y) {
|
||||||
if (x > 10) // expected-note {{silence}}
|
if (x > 10) // expected-note {{silence}}
|
||||||
calledFun(); // expected-warning {{will never be executed}}
|
calledFun(); // expected-warning {{will never be executed}}
|
||||||
|
|
Loading…
Reference in New Issue