https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/159911
>From ad8fc039e1aea131c56c356e88c8c1a4c9afe737 Mon Sep 17 00:00:00 2001 From: Congcong Cai <[email protected]> Date: Fri, 19 Sep 2025 23:28:30 +0800 Subject: [PATCH 1/4] [clang-tidy] add readability-redundant-parentheses This check wants to detect a common happened case that forgetting to remove parenthese during modifying code. --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../readability/ReadabilityTidyModule.cpp | 3 + .../readability/RedundantParenthesesCheck.cpp | 54 +++++++++++++++++ .../readability/RedundantParenthesesCheck.h | 31 ++++++++++ clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../docs/clang-tidy/checks/list.rst | 1 + .../readability/redundant-parentheses.rst | 29 ++++++++++ .../readability/redundant-parentheses.cpp | 58 +++++++++++++++++++ 8 files changed, 182 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 4b4c49d3b17d1..0d0641c4b22bf 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -44,6 +44,7 @@ add_clang_library(clangTidyReadabilityModule STATIC RedundantDeclarationCheck.cpp RedundantFunctionPtrDereferenceCheck.cpp RedundantMemberInitCheck.cpp + RedundantParenthesesCheck.cpp RedundantPreprocessorCheck.cpp RedundantSmartptrGetCheck.cpp RedundantStringCStrCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index d01882dfc9daa..fcfac05b000e4 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -47,6 +47,7 @@ #include "RedundantFunctionPtrDereferenceCheck.h" #include "RedundantInlineSpecifierCheck.h" #include "RedundantMemberInitCheck.h" +#include "RedundantParenthesesCheck.h" #include "RedundantPreprocessorCheck.h" #include "RedundantSmartptrGetCheck.h" #include "RedundantStringCStrCheck.h" @@ -138,6 +139,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-redundant-function-ptr-dereference"); CheckFactories.registerCheck<RedundantMemberInitCheck>( "readability-redundant-member-init"); + CheckFactories.registerCheck<RedundantParenthesesCheck>( + "readability-redundant-parentheses"); CheckFactories.registerCheck<RedundantPreprocessorCheck>( "readability-redundant-preprocessor"); CheckFactories.registerCheck<ReferenceToConstructedTemporaryCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp new file mode 100644 index 0000000000000..6517f68216787 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp @@ -0,0 +1,54 @@ + +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RedundantParenthesesCheck.h" +#include "clang/AST/Expr.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include <cassert> + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +namespace { + +AST_MATCHER_P(ParenExpr, subExpr, ast_matchers::internal::Matcher<Expr>, + InnerMatcher) { + return InnerMatcher.matches(*Node.getSubExpr(), Finder, Builder); +} + +} // namespace + +void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + parenExpr(subExpr(anyOf(parenExpr(), integerLiteral(), floatLiteral(), + characterLiteral(), cxxBoolLiteral(), + stringLiteral(), declRefExpr())), + unless( + // sizeof(...) is common used. + hasParent(unaryExprOrTypeTraitExpr()))) + .bind("dup"), + this); +} + +void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) { + const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup"); + assert(PE); + const Expr *E = PE->getSubExpr(); + if (PE->getLParen().isMacroID() || PE->getRParen().isMacroID() || + E->getBeginLoc().isMacroID() || E->getEndLoc().isMacroID()) + return; + diag(PE->getBeginLoc(), "redundant parentheses around expression") + << FixItHint::CreateRemoval(PE->getLParen()) + << FixItHint::CreateRemoval(PE->getRParen()); +} + +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h new file mode 100644 index 0000000000000..8806fb391ba26 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h @@ -0,0 +1,31 @@ + +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Detect redundant parentheses. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-parentheses.html +class RedundantParenthesesCheck : public ClangTidyCheck { +public: + RedundantParenthesesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index a4652a7a54858..1dbacaf061b73 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -203,6 +203,11 @@ New checks Finds virtual function overrides with different visibility than the function in the base class. +- New :doc:`readability-redundant-parentheses + <clang-tidy/checks/readability/redundant-parentheses>` check. + + Detect redundant parentheses. + New check aliases ^^^^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index e06849c419389..51d968895044c 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -404,6 +404,7 @@ Clang-Tidy Checks :doc:`readability-redundant-function-ptr-dereference <readability/redundant-function-ptr-dereference>`, "Yes" :doc:`readability-redundant-inline-specifier <readability/redundant-inline-specifier>`, "Yes" :doc:`readability-redundant-member-init <readability/redundant-member-init>`, "Yes" + :doc:`readability-redundant-parentheses <readability/redundant-parentheses>`, "Yes" :doc:`readability-redundant-preprocessor <readability/redundant-preprocessor>`, :doc:`readability-redundant-smartptr-get <readability/redundant-smartptr-get>`, "Yes" :doc:`readability-redundant-string-cstr <readability/redundant-string-cstr>`, "Yes" 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 new file mode 100644 index 0000000000000..09f9113b89cbd --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-parentheses.rst @@ -0,0 +1,29 @@ +.. title:: clang-tidy - readability-redundant-parentheses + +readability-redundant-parentheses +================================= + +Detect redundant parentheses. + +When modifying the code, one often forgets to remove the corresponding parentheses. +This results in overly lengthy code. When the expression is complex, finding +the matching parentheses becomes particularly difficult. + +Example +------- + +.. code-block:: c++ + + (1); + ((a + 2)) * 3; + (a); + ("aaa"); + +Currently this check does not take into account the precedence of operations. +Even if the expression within the parentheses has a higher priority than that +outside the parentheses, in other words, removing the parentheses will not +affect the semantic. + +.. code-block:: c++ + + int a = (1 * 2) + 3; // no warning 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 new file mode 100644 index 0000000000000..017f22ec75721 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-parentheses.cpp @@ -0,0 +1,58 @@ +// RUN: %check_clang_tidy %s readability-redundant-parentheses %t + +void parenExpr() { + 1 + 1; + (1 + 1); + ((1 + 1)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: (1 + 1); + (((1 + 1))); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-MESSAGES: :[[@LINE-2]]:4: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: (1 + 1); + ((((1 + 1)))); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-MESSAGES: :[[@LINE-2]]:4: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: (1 + 1); +} + +#define EXP (1 + 1) +#define PAREN(e) (e) +void parenExprWithMacro() { + EXP; // 1 + (EXP); // 2 + ((EXP)); // 3 + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: (EXP); // 3 + PAREN((1)); +} + +void constant() { + (1); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: 1; + (1.0); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: 1.0; + (true); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: true; + (','); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: ','; + ("v4"); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: "v4"; +} + +void declRefExpr(int a) { + (a); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses] + // CHECK-FIXES: a; +} + +void exceptions() { + sizeof(1); + alignof(2); +} >From 863331fc7a6ff0c8a3e68d355e65704964763413 Mon Sep 17 00:00:00 2001 From: Congcong Cai <[email protected]> Date: Mon, 22 Sep 2025 09:52:23 +0800 Subject: [PATCH 2/4] fix reviwe --- .../clang-tidy/readability/RedundantParenthesesCheck.cpp | 1 - .../clang-tidy/readability/RedundantParenthesesCheck.h | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp index 6517f68216787..57b1dc949868a 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h index 8806fb391ba26..43e244669fa2b 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -11,6 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H #include "../ClangTidyCheck.h" +#include "clang/Basic/LangOptions.h" namespace clang::tidy::readability { @@ -24,6 +24,9 @@ class RedundantParenthesesCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context) {} 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; + } }; } // namespace clang::tidy::readability >From 92db7842096a9850f1bb270e87d1249500965b04 Mon Sep 17 00:00:00 2001 From: Congcong Cai <[email protected]> Date: Tue, 23 Sep 2025 15:32:07 +0800 Subject: [PATCH 3/4] Update clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h Co-authored-by: Victor Chernyakin <[email protected]> --- .../clang-tidy/readability/RedundantParenthesesCheck.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h index 43e244669fa2b..9a0409b83fff3 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.h @@ -17,7 +17,7 @@ namespace clang::tidy::readability { /// Detect redundant parentheses. /// /// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-parentheses.html +/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-parentheses.html class RedundantParenthesesCheck : public ClangTidyCheck { public: RedundantParenthesesCheck(StringRef Name, ClangTidyContext *Context) >From 42aab95490f6e6281a4b5f35d4ee34c584171826 Mon Sep 17 00:00:00 2001 From: Congcong Cai <[email protected]> Date: Thu, 25 Sep 2025 22:50:52 +0800 Subject: [PATCH 4/4] fix review --- .../readability/RedundantParenthesesCheck.cpp | 17 +++++++++-------- 1 file 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 57b1dc949868a..94ea823b18fc0 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp @@ -24,6 +24,12 @@ AST_MATCHER_P(ParenExpr, subExpr, ast_matchers::internal::Matcher<Expr>, return InnerMatcher.matches(*Node.getSubExpr(), Finder, Builder); } +AST_MATCHER(ParenExpr, isInMacro) { + const Expr *E = Node.getSubExpr(); + return Node.getLParen().isMacroID() || Node.getRParen().isMacroID() || + E->getBeginLoc().isMacroID() || E->getEndLoc().isMacroID(); +} + } // namespace void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) { @@ -31,20 +37,15 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) { parenExpr(subExpr(anyOf(parenExpr(), integerLiteral(), floatLiteral(), characterLiteral(), cxxBoolLiteral(), stringLiteral(), declRefExpr())), - unless( - // sizeof(...) is common used. - hasParent(unaryExprOrTypeTraitExpr()))) + 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"); - assert(PE); - const Expr *E = PE->getSubExpr(); - if (PE->getLParen().isMacroID() || PE->getRParen().isMacroID() || - E->getBeginLoc().isMacroID() || E->getEndLoc().isMacroID()) - return; diag(PE->getBeginLoc(), "redundant parentheses around expression") << FixItHint::CreateRemoval(PE->getLParen()) << FixItHint::CreateRemoval(PE->getRParen()); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
