Author: Gaurav Dhingra Date: 2026-05-28T13:22:53+08:00 New Revision: 1da70ad6da64e5737aae1b8aad1bc97a36bbe1cf
URL: https://github.com/llvm/llvm-project/commit/1da70ad6da64e5737aae1b8aad1bc97a36bbe1cf DIFF: https://github.com/llvm/llvm-project/commit/1da70ad6da64e5737aae1b8aad1bc97a36bbe1cf.diff LOG: [clang-tidy] Fix false positive of parentheses removal for overloaded operator (#192254) Fixes #189217 don't remove necessary parentheses for an overloaded operator, when the parenthese occurs in the context of a binary operation E.g. (E1 & E2) != E3 // the brackets aren't redundant here E.g. (E1 & E2) // brackets are redundant here Added: Modified: clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp index 9b3948a1c50c0..c177c07b95a75 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp @@ -55,7 +55,7 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) { parenExpr(), ConstantExpr, declRefExpr(to(namedDecl(unless( matchers::matchesAnyListedRegexName(AllowedDecls))))), - memberExpr(), callExpr())), + memberExpr(), callExpr(unless(cxxOperatorCallExpr())))), unless(anyOf(isInMacro(), // sizeof(...) is common used. hasParent(unaryExprOrTypeTraitExpr())))) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index f1b49e2cb6056..0b3bb091307e7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -728,6 +728,11 @@ Changes in existing checks `IgnoreMacros` option to suppress warnings when the initializer involves macros that may expand diff erently in other configurations. +- Improved :doc:`readability-redundant-parentheses + <clang-tidy/checks/readability/redundant-parentheses>` check by fixing a + false positive for parentheses present around an overloaded operator in the + context of a binary operation. + - Improved :doc:`readability-redundant-preprocessor <clang-tidy/checks/readability/redundant-preprocessor>` check by fixing a false positive for nested ``#if`` directives using diff erent builtin diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp index 9a8a0d4d73483..83c6f94d1a09f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp @@ -121,3 +121,90 @@ void memberExpr() { // CHECK-FIXES: if (foo.fooBar().z) { } } + +enum class FoldLevel { + None = 0x0, + HeaderFlag = 0x2000, +}; + +int FoldLevelToInt(FoldLevel l) { + return static_cast<int>(l); +} + +constexpr FoldLevel operator&(FoldLevel lhs, FoldLevel rhs) { + return static_cast<FoldLevel>(static_cast<int>(lhs) & static_cast<int>(rhs)); +} + +constexpr FoldLevel operator*(FoldLevel lhs, FoldLevel rhs) { + return static_cast<FoldLevel>(static_cast<int>(lhs) * static_cast<int>(rhs)); +} + +constexpr FoldLevel operator!(FoldLevel operand) { + return static_cast<FoldLevel>(!static_cast<int>(operand)); +} + + +constexpr FoldLevel operator+(FoldLevel lhs, FoldLevel rhs) { + return lhs; +} + +constexpr bool UseOperatorAmpersand1(FoldLevel level) { + return (level & FoldLevel::HeaderFlag) != FoldLevel::None; +} + +constexpr bool UseOperatorAmpersand2(FoldLevel level) { + const FoldLevel l = level & FoldLevel::HeaderFlag; + return (l != FoldLevel::None); +} + +constexpr bool UseOperatorAmpersand3(FoldLevel level) { + return ((level & FoldLevel::HeaderFlag) != FoldLevel::None); +} + +constexpr bool UseOperatorAmpersand4(FoldLevel level) { + return FoldLevel::None != (level & FoldLevel::HeaderFlag); +} + +constexpr bool UseOperatorAmpersand5(FoldLevel level) { + FoldLevel hf = FoldLevel::HeaderFlag; + // currently this check doesn't take into account order of operations, so the + // parentheses around `left & rhs` is needed + return ((level & hf) * hf) != FoldLevel::None; +} + +constexpr bool UseOperatorAmpersand6(FoldLevel level) { + FoldLevel hf = FoldLevel::HeaderFlag; + return (!(level & hf) * hf) != FoldLevel::None; +} + +constexpr FoldLevel UseOperatorAmpersand7(FoldLevel level) { + FoldLevel hf = FoldLevel::HeaderFlag; + return !(level & hf) * hf; +} + +constexpr FoldLevel UseOperatorAmpersand8(FoldLevel level) { + FoldLevel hf = FoldLevel::HeaderFlag; + return hf * !(level & hf); +} + +constexpr FoldLevel UseOperatorAmpersand9(FoldLevel level) { + FoldLevel hf = FoldLevel::HeaderFlag; + return !(level & hf); +} + +constexpr bool UseOperatorPlus1(FoldLevel level) { + return (FoldLevelToInt(level + FoldLevel::None)) != 1; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: return FoldLevelToInt(level + FoldLevel::None) != 1; +} + +constexpr bool UseOperatorPlus2(FoldLevel level) { + return (FoldLevelToInt(!(level + FoldLevel::None))) != 1; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: return FoldLevelToInt(!(level + FoldLevel::None)) != 1; +} + + +const int bracket_int_plus_num = (4) + 5; +// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant parentheses around expression [readability-redundant-parentheses] +// CHECK-FIXES: const int bracket_int_plus_num = 4 + 5; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
