r206360 - -Wunreachable-code: refine recognition of unreachable "sigil" to cope with implicit casts in C++.
Ted Kremenek
kremenek at apple.com
Wed Apr 16 00:26:09 PDT 2014
Author: kremenek
Date: Wed Apr 16 02:26:09 2014
New Revision: 206360
URL: http://llvm.org/viewvc/llvm-project?rev=206360&view=rev
Log:
-Wunreachable-code: refine recognition of unreachable "sigil" to cope with implicit casts in C++.
Fixes <rdar://problem/16631033>.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Analysis/ReachableCode.cpp
cfe/trunk/test/SemaCXX/warn-unreachable.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=206360&r1=206359&r2=206360&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Apr 16 02:26:09 2014
@@ -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);
}
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=206360&r1=206359&r2=206360&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Wed Apr 16 02:26:09 2014
@@ -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
Modified: cfe/trunk/lib/Analysis/ReachableCode.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ReachableCode.cpp?rev=206360&r1=206359&r2=206360&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ReachableCode.cpp (original)
+++ cfe/trunk/lib/Analysis/ReachableCode.cpp Wed Apr 16 02:26:09 2014
@@ -139,6 +139,9 @@ static bool isConfigurationValue(const 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 S
IncludeIntegers, true);
if (const Expr *Ex = dyn_cast<Expr>(S))
- S = Ex->IgnoreParenCasts();
+ S = Ex->IgnoreCasts();
bool IgnoreYES_NO = false;
Modified: cfe/trunk/test/SemaCXX/warn-unreachable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unreachable.cpp?rev=206360&r1=206359&r2=206360&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unreachable.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unreachable.cpp Wed Apr 16 02:26:09 2014
@@ -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}}
More information about the cfe-commits
mailing list