[clang-tools-extra] [clang-tidy][readability-redundant-parentheses] add option to prevent widely used work around (PR #164827)
Congcong Cai via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 23 19:25:32 PDT 2025
https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/164827
>From 525b01535ccde73b341231fccf4d493fc1433914 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Thu, 23 Oct 2025 22:36:40 +0800
Subject: [PATCH 1/2] [clang-tidy][readability-redundant-parentheses] add
option to prevent widely used work around
Fixed: #164125
Add a new option to ignore some decls.
Because it is a new check in this version, no release note needs to be updated.
---
.../readability/RedundantParenthesesCheck.cpp | 22 +++++++++++++++++++
.../readability/RedundantParenthesesCheck.h | 7 ++++--
.../readability/redundant-parentheses.rst | 13 +++++++++++
.../readability/redundant-parentheses.cpp | 9 ++++++++
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 0ab59fff39d88..2b5cf12603609 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "RedundantParenthesesCheck.h"
+#include "../utils/OptionsUtils.h"
#include "clang/AST/Expr.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -32,6 +33,18 @@ AST_MATCHER(ParenExpr, isInMacro) {
} // namespace
+RedundantParenthesesCheck::RedundantParenthesesCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ AllowedDecls(utils::options::parseStringList(
+ Options.get("AllowedDecls", "std::max;std::min"))) {}
+
+void RedundantParenthesesCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "AllowedDecls",
+ utils::options::serializeStringList(AllowedDecls));
+}
+
void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) {
const auto ConstantExpr =
expr(anyOf(integerLiteral(), floatLiteral(), characterLiteral(),
@@ -47,6 +60,15 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) {
void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup");
+ if (auto *DRE = dyn_cast<DeclRefExpr>(PE->getSubExpr())) {
+ const std::string Name = DRE->getDecl()->getQualifiedNameAsString();
+ llvm::errs() << Name << "\n";
+ bool Allowed = llvm::any_of(AllowedDecls, [&Name](const llvm::Regex &NM) {
+ return NM.isValid() && NM.match(Name);
+ });
+ if (Allowed)
+ return;
+ }
diag(PE->getBeginLoc(), "redundant parentheses around expression")
<< FixItHint::CreateRemoval(PE->getLParen())
<< FixItHint::CreateRemoval(PE->getRParen());
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h
index 9a0409b83fff3..2638a09730f7e 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h
@@ -20,13 +20,16 @@ namespace clang::tidy::readability {
/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-parentheses.html
class RedundantParenthesesCheck : public ClangTidyCheck {
public:
- RedundantParenthesesCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ RedundantParenthesesCheck(StringRef Name, ClangTidyContext *Context);
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus | LangOpts.C99;
}
+
+private:
+ const std::vector<StringRef> AllowedDecls;
};
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst
index 23d975e646490..66b31fae2f2ed 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst
@@ -27,3 +27,16 @@ affect the semantics.
.. code-block:: c++
int a = (1 * 2) + 3; // no warning
+
+Options
+-------
+
+.. option:: AllowedDecls
+
+ A semicolon-separated list of names of declarations included variables and
+ functions to ignore when the parenthese around it.
+ The default is an `std::max;std::min`.
+
+ Some std library functions may have the same name as widely used function-like
+ macro. For example, ``std::max`` and ``max`` macro. A work around to distinguish
+ them is adding parenthese around functions to prevent function-like macro.
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 926cb118c77cf..c77608c66469c 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
@@ -62,3 +62,12 @@ void exceptions() {
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant parentheses around expression [readability-redundant-parentheses]
// CHECK-FIXES: alignof(3);
}
+
+namespace std {
+ template<class T> T max(T, T);
+ template<class T> T min(T, T);
+} // namespace std
+void ignoreStdMaxMin() {
+ (std::max)(1,2);
+ (std::min)(1,2);
+}
>From 8f84ad5ce977673e442304d7aa05d3b11dab5cbb Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0907 at 163.com>
Date: Fri, 24 Oct 2025 10:25:25 +0800
Subject: [PATCH 2/2] Update
clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
---
.../clang-tidy/readability/RedundantParenthesesCheck.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 2b5cf12603609..f653881f93769 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -62,7 +62,6 @@ void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup");
if (auto *DRE = dyn_cast<DeclRefExpr>(PE->getSubExpr())) {
const std::string Name = DRE->getDecl()->getQualifiedNameAsString();
- llvm::errs() << Name << "\n";
bool Allowed = llvm::any_of(AllowedDecls, [&Name](const llvm::Regex &NM) {
return NM.isValid() && NM.match(Name);
});
More information about the cfe-commits
mailing list