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 @@ -569,6 +569,7 @@ std::string SwapId = (Id + "-swap").str(); std::string NegateId = (Id + "-negate").str(); std::string OverloadId = (Id + "-overload").str(); + std::string ConstId = (Id + "-const").str(); const auto RelationalExpr = ignoringParenImpCasts(binaryOperator( isComparisonOperator(), expr().bind(Id), @@ -600,7 +601,8 @@ cxxOperatorCallExpr( hasAnyOverloadedOperatorName("==", "!=", "<", "<=", ">", ">="), // Filter noisy false positives. - unless(isMacro()), unless(isInTemplateInstantiation())) + unless(isMacro()), unless(isInTemplateInstantiation()), + hasRHS(ignoringParenImpCasts(integerLiteral().bind(ConstId)))) .bind(OverloadId); return anyOf(RelationalExpr, CastExpr, NegateRelationalExpr, @@ -683,6 +685,9 @@ OperandExpr = OverloadedOperatorExpr; Opcode = BinaryOperator::getOverloadedOpcode(OverloadedOperatorExpr->getOperator()); + if (!retrieveIntegerConstantExpr(Result, Id, Value, ConstExpr)) + return false; + return BinaryOperator::isComparisonOp(Opcode); } else { return false; 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 @@ -453,6 +453,11 @@ if (s1 >= 1 || s1 <= 1) return true; // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true + // Test for absence of false positives (issue #54011). + if (s1 == 1 || s1 == 2) return true; + if (s1 > 1 && s1 < 3) return true; + if (s1 >= 2 || s1 <= 0) return true; + // Test for overloaded operators that may modify their params. S2 s2; if (s2 == 1 || s2 != 1) return true;