Index: clang/include/clang/AST/Stmt.h =================================================================== --- clang/include/clang/AST/Stmt.h +++ clang/include/clang/AST/Stmt.h @@ -387,6 +387,9 @@ /// Skip past any implicit AST nodes which might surround this /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes. Stmt *IgnoreImplicit(); + const Stmt *IgnoreImplicit() const { + return const_cast(this)->IgnoreImplicit(); + } /// \brief Skip no-op (attributed, compound) container stmts and skip captured /// stmt at the top, if \a IgnoreCaptured is true. Index: clang/lib/Analysis/ReachableCode.cpp =================================================================== --- clang/lib/Analysis/ReachableCode.cpp +++ clang/lib/Analysis/ReachableCode.cpp @@ -164,6 +164,8 @@ if (!S) return false; + S = S->IgnoreImplicit(); + if (const Expr *Ex = dyn_cast(S)) S = Ex->IgnoreCasts(); Index: clang/test/SemaCXX/PR29152.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/PR29152.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunreachable-code -verify %s + +static const bool False = false; + +struct Vector { + struct iterator { + bool operator==(const iterator &) const; + }; + iterator end(); +}; + +void Bar(); +Vector::iterator Find(Vector &a); + +void Foo(Vector &a) { + if (False && Find(a) == a.end()) { + Bar(); // expected-no-diagnostics + } +}