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 <[email protected]> Date: Thu, 23 Oct 2025 22:36:40 +0800 Subject: [PATCH 1/4] [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 <[email protected]> Date: Fri, 24 Oct 2025 10:25:25 +0800 Subject: [PATCH 2/4] 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); }); >From 5e37c831304d9f10b75898024c0ca1b331e68868 Mon Sep 17 00:00:00 2001 From: Congcong Cai <[email protected]> Date: Fri, 24 Oct 2025 12:38:42 +0800 Subject: [PATCH 3/4] fix review --- .../readability/RedundantParenthesesCheck.cpp | 7 ++++--- .../checks/readability/redundant-parentheses.rst | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp index f653881f93769..9a129a3f63b92 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp @@ -62,9 +62,10 @@ 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(); - bool Allowed = llvm::any_of(AllowedDecls, [&Name](const llvm::Regex &NM) { - return NM.isValid() && NM.match(Name); - }); + const bool Allowed = + llvm::any_of(AllowedDecls, [&Name](const llvm::Regex &NM) { + return NM.isValid() && NM.match(Name); + }); if (Allowed) return; } 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 66b31fae2f2ed..4802a95a52534 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 @@ -33,10 +33,10 @@ Options .. option:: AllowedDecls - A semicolon-separated list of names of declarations included variables and - functions to ignore when the parenthese around it. + A semicolon-separated list of names of declarations to ignore when the + parentheses are around. Declarations can include variables or functions. 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. + Some STL library functions may have the same name as widely used function-like + macro. For example, ``std::max`` and ``max`` macro. A workaround to distinguish + them is adding parentheses around functions to prevent function-like macro. >From 50e451f56b91d491c87f82ec5e89d42f5c7c566e Mon Sep 17 00:00:00 2001 From: Congcong Cai <[email protected]> Date: Tue, 28 Oct 2025 11:03:05 +0800 Subject: [PATCH 4/4] fix reviwe --- .../readability/RedundantParenthesesCheck.cpp | 21 +++++++------------ .../readability/redundant-parentheses.rst | 5 +++-- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp index 9a129a3f63b92..874b9618bd882 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/Matchers.h" #include "../utils/OptionsUtils.h" #include "clang/AST/Expr.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -50,25 +51,19 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) { expr(anyOf(integerLiteral(), floatLiteral(), characterLiteral(), cxxBoolLiteral(), stringLiteral(), cxxNullPtrLiteralExpr())); Finder->addMatcher( - parenExpr(subExpr(anyOf(parenExpr(), ConstantExpr, declRefExpr())), - unless(anyOf(isInMacro(), - // sizeof(...) is common used. - hasParent(unaryExprOrTypeTraitExpr())))) + parenExpr( + subExpr(anyOf(parenExpr(), ConstantExpr, + declRefExpr(to(namedDecl(unless( + matchers::matchesAnyListedName(AllowedDecls))))))), + unless(anyOf(isInMacro(), + // sizeof(...) is common used. + hasParent(unaryExprOrTypeTraitExpr())))) .bind("dup"), this); } 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(); - const 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/docs/clang-tidy/checks/readability/redundant-parentheses.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst index 4802a95a52534..491983d34cd83 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 @@ -33,8 +33,9 @@ Options .. option:: AllowedDecls - A semicolon-separated list of names of declarations to ignore when the - parentheses are around. Declarations can include variables or functions. + Semicolon-separated list of regular expressions matching names of declarations + to ignore when the parentheses are around. Declarations can include variables + or functions. The default is an `std::max;std::min`. Some STL library functions may have the same name as widely used function-like _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
