/// 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;
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);
}
}
}
+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
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())
IncludeIntegers, true);
if (const Expr *Ex = dyn_cast<Expr>(S))
- S = Ex->IgnoreParenCasts();
+ S = Ex->IgnoreCasts();
bool IgnoreYES_NO = false;
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}}