diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp @@ -72,8 +72,8 @@ Expr::const_child_iterator LeftIter = Left->child_begin(); Expr::const_child_iterator RightIter = Right->child_begin(); while (LeftIter != Left->child_end() && RightIter != Right->child_end()) { - if (!areEquivalentExpr(dyn_cast(*LeftIter), - dyn_cast(*RightIter))) + if (!areEquivalentExpr(dyn_cast_or_null(*LeftIter), + dyn_cast_or_null(*RightIter))) return false; ++LeftIter; ++RightIter; @@ -117,6 +117,9 @@ case Stmt::MemberExprClass: return cast(Left)->getMemberDecl() == cast(Right)->getMemberDecl(); + case Stmt::CXXFoldExprClass: + return cast(Left)->getOperator() == + cast(Right)->getOperator(); case Stmt::CXXFunctionalCastExprClass: case Stmt::CStyleCastExprClass: return cast(Left)->getTypeAsWritten() == diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp @@ -793,4 +793,10 @@ return foo < GetFoo() && foo < maybe_foo; } }; -} + +template +struct Bar2 { + static_assert((... && (sizeof(Values) > 0)) == (... && (sizeof(Values) > 0))); + // CHECK-MESSAGES: :[[@LINE-1]]:47: warning: both sides of operator are equivalent [misc-redundant-expression] +}; +} // namespace no_crash