[clang-tools-extra] [clang-tidy] Fix false positive in readability-redundant-parentheses … (PR #192827)
Yuta Nakamura via cfe-commits
cfe-commits at lists.llvm.org
Sun Apr 19 21:23:28 PDT 2026
https://github.com/nakasan617 updated https://github.com/llvm/llvm-project/pull/192827
>From d7260fe29de6a9fa2e1b01495a8e50feaa6d22f8 Mon Sep 17 00:00:00 2001
From: Yuta Nakamura <yutanak6 at gmail.com>
Date: Sun, 19 Apr 2026 21:13:13 -0700
Subject: [PATCH] [clang-tidy] Fix false positive in
readability-redundant-parentheses for overloaded operators
Overloaded comparison operators (e.g. iterator !=, std::string >=) are
represented as CXXOperatorCallExpr, a subclass of CallExpr. The matcher
previously matched all CallExpr, causing spurious warnings for parenthesized
overloaded-operator expressions while silently accepting equivalent built-in
operator expressions (e.g. int == int).
This fix excludes CXXOperatorCallExpr from the CallExpr match, except for
operator() (functor calls), which are treated like regular function calls.
This makes the check consistent: overloaded operators in operator form are
treated the same as built-in binary operators.
Fixes #192463, #192438, #192435.
---
.../readability/RedundantParenthesesCheck.cpp | 4 ++-
clang-tools-extra/docs/ReleaseNotes.rst | 8 +++++
.../readability/redundant-parentheses.cpp | 33 +++++++++++++++++++
3 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 9b3948a1c50c0..e52af57a49127 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -55,7 +55,9 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) {
parenExpr(), ConstantExpr,
declRefExpr(to(namedDecl(unless(
matchers::matchesAnyListedRegexName(AllowedDecls))))),
- memberExpr(), callExpr())),
+ memberExpr(),
+ callExpr(unless(cxxOperatorCallExpr(
+ unless(hasOverloadedOperatorName("()")))))),
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 95ed0061d654c..ec17ae71f9123 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -230,6 +230,14 @@ New check aliases
Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^
+- Improved :doc:`readability-redundant-parentheses
+ <clang-tidy/checks/readability/redundant-parentheses>` check to fix a false
+ positive where parentheses around overloaded comparison operators (e.g.
+ ``iterator !=``, ``std::string >=``) were incorrectly flagged while
+ equivalent built-in operator expressions were not. Overloaded operators
+ written in operator form are now treated consistently with built-in binary
+ operators. Functor calls via ``operator()`` continue to be flagged.
+
- Improved :doc:`bugprone-argument-comment
<clang-tidy/checks/bugprone/argument-comment>` to also check for C++11
inherited constructors.
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..212b60d424d23 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
@@ -99,6 +99,39 @@ struct Foo
}
};
+struct Iterator {
+ bool operator!=(const Iterator &) const;
+ bool operator>=(const Iterator &) const;
+};
+
+struct Functor {
+ bool operator()() const;
+};
+
+void overloadedOperators() {
+ Iterator it, end;
+
+ // Single parens around overloaded operator: no warning (consistent with
+ // built-in binary operators, which are not in the matcher).
+ if ((it != end)) {
+ }
+ if ((it >= end)) {
+ }
+
+ // Double parens: outer paren wraps a ParenExpr, so outer paren still warns.
+ if (((it != end))) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant parentheses around expression [readability-redundant-parentheses]
+ // CHECK-FIXES: if ((it != end)) {
+ }
+
+ // Functor call via operator(): still warns (treated like a regular call).
+ Functor f{};
+ if ((f())) {
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant parentheses around expression [readability-redundant-parentheses]
+ // CHECK-FIXES: if (f()) {
+ }
+}
+
void memberExpr() {
Foo foo{};
if ((foo.x)) {
More information about the cfe-commits
mailing list