Skip to content

Commit 85aeb6a

Browse files
HerrCai0907localspookvbvictor
authored
[clang-tidy] add readability-redundant-parentheses (#159911)
This check wants to detect a common happened case that forgetting to remove parenthese during modifying code. --------- Co-authored-by: Victor Chernyakin <chernyakin.victor.j@outlook.com> Co-authored-by: Baranov Victor <bar.victor.2002@gmail.com>
1 parent 4a19406 commit 85aeb6a

File tree

8 files changed

+192
-0
lines changed

8 files changed

+192
-0
lines changed

clang-tools-extra/clang-tidy/readability/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
4444
RedundantDeclarationCheck.cpp
4545
RedundantFunctionPtrDereferenceCheck.cpp
4646
RedundantMemberInitCheck.cpp
47+
RedundantParenthesesCheck.cpp
4748
RedundantPreprocessorCheck.cpp
4849
RedundantSmartptrGetCheck.cpp
4950
RedundantStringCStrCheck.cpp

clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "RedundantFunctionPtrDereferenceCheck.h"
4848
#include "RedundantInlineSpecifierCheck.h"
4949
#include "RedundantMemberInitCheck.h"
50+
#include "RedundantParenthesesCheck.h"
5051
#include "RedundantPreprocessorCheck.h"
5152
#include "RedundantSmartptrGetCheck.h"
5253
#include "RedundantStringCStrCheck.h"
@@ -138,6 +139,8 @@ class ReadabilityModule : public ClangTidyModule {
138139
"readability-redundant-function-ptr-dereference");
139140
CheckFactories.registerCheck<RedundantMemberInitCheck>(
140141
"readability-redundant-member-init");
142+
CheckFactories.registerCheck<RedundantParenthesesCheck>(
143+
"readability-redundant-parentheses");
141144
CheckFactories.registerCheck<RedundantPreprocessorCheck>(
142145
"readability-redundant-preprocessor");
143146
CheckFactories.registerCheck<ReferenceToConstructedTemporaryCheck>(
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "RedundantParenthesesCheck.h"
10+
#include "clang/AST/Expr.h"
11+
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "clang/ASTMatchers/ASTMatchers.h"
13+
#include "clang/ASTMatchers/ASTMatchersMacros.h"
14+
#include <cassert>
15+
16+
using namespace clang::ast_matchers;
17+
18+
namespace clang::tidy::readability {
19+
20+
namespace {
21+
22+
AST_MATCHER_P(ParenExpr, subExpr, ast_matchers::internal::Matcher<Expr>,
23+
InnerMatcher) {
24+
return InnerMatcher.matches(*Node.getSubExpr(), Finder, Builder);
25+
}
26+
27+
AST_MATCHER(ParenExpr, isInMacro) {
28+
const Expr *E = Node.getSubExpr();
29+
return Node.getLParen().isMacroID() || Node.getRParen().isMacroID() ||
30+
E->getBeginLoc().isMacroID() || E->getEndLoc().isMacroID();
31+
}
32+
33+
} // namespace
34+
35+
void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) {
36+
const auto ConstantExpr =
37+
expr(anyOf(integerLiteral(), floatLiteral(), characterLiteral(),
38+
cxxBoolLiteral(), stringLiteral(), cxxNullPtrLiteralExpr()));
39+
Finder->addMatcher(
40+
parenExpr(subExpr(anyOf(parenExpr(), ConstantExpr, declRefExpr())),
41+
unless(anyOf(isInMacro(),
42+
// sizeof(...) is common used.
43+
hasParent(unaryExprOrTypeTraitExpr()))))
44+
.bind("dup"),
45+
this);
46+
}
47+
48+
void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
49+
const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup");
50+
diag(PE->getBeginLoc(), "redundant parentheses around expression")
51+
<< FixItHint::CreateRemoval(PE->getLParen())
52+
<< FixItHint::CreateRemoval(PE->getRParen());
53+
}
54+
55+
} // namespace clang::tidy::readability
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
#include "clang/Basic/LangOptions.h"
14+
15+
namespace clang::tidy::readability {
16+
17+
/// Detect redundant parentheses.
18+
///
19+
/// For the user-facing documentation see:
20+
/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-parentheses.html
21+
class RedundantParenthesesCheck : public ClangTidyCheck {
22+
public:
23+
RedundantParenthesesCheck(StringRef Name, ClangTidyContext *Context)
24+
: ClangTidyCheck(Name, Context) {}
25+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
26+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
27+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
28+
return LangOpts.CPlusPlus | LangOpts.C99;
29+
}
30+
};
31+
32+
} // namespace clang::tidy::readability
33+
34+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTPARENTHESESCHECK_H

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ New checks
203203
Finds virtual function overrides with different visibility than the function
204204
in the base class.
205205

206+
- New :doc:`readability-redundant-parentheses
207+
<clang-tidy/checks/readability/redundant-parentheses>` check.
208+
209+
Detect redundant parentheses.
210+
206211
New check aliases
207212
^^^^^^^^^^^^^^^^^
208213

clang-tools-extra/docs/clang-tidy/checks/list.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ Clang-Tidy Checks
404404
:doc:`readability-redundant-function-ptr-dereference <readability/redundant-function-ptr-dereference>`, "Yes"
405405
:doc:`readability-redundant-inline-specifier <readability/redundant-inline-specifier>`, "Yes"
406406
:doc:`readability-redundant-member-init <readability/redundant-member-init>`, "Yes"
407+
:doc:`readability-redundant-parentheses <readability/redundant-parentheses>`, "Yes"
407408
:doc:`readability-redundant-preprocessor <readability/redundant-preprocessor>`,
408409
:doc:`readability-redundant-smartptr-get <readability/redundant-smartptr-get>`, "Yes"
409410
:doc:`readability-redundant-string-cstr <readability/redundant-string-cstr>`, "Yes"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.. title:: clang-tidy - readability-redundant-parentheses
2+
3+
readability-redundant-parentheses
4+
=================================
5+
6+
Detect redundant parentheses.
7+
8+
When modifying code, one often forgets to remove the corresponding parentheses.
9+
This results in overly lengthy code. When the expression is complex, finding
10+
the matching parentheses becomes particularly difficult.
11+
12+
Example
13+
-------
14+
15+
.. code-block:: c++
16+
17+
(1);
18+
((a + 2)) * 3;
19+
(a);
20+
("aaa");
21+
22+
Currently this check does not take into account the precedence of operations.
23+
Even if the expression within the parentheses has a higher priority than that
24+
outside the parentheses. In other words, removing the parentheses will not
25+
affect the semantics.
26+
27+
.. code-block:: c++
28+
29+
int a = (1 * 2) + 3; // no warning
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %check_clang_tidy %s readability-redundant-parentheses %t
2+
3+
void parenExpr() {
4+
1 + 1;
5+
(1 + 1);
6+
((1 + 1));
7+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
8+
// CHECK-FIXES: (1 + 1);
9+
(((1 + 1)));
10+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
11+
// CHECK-MESSAGES: :[[@LINE-2]]:4: warning: redundant parentheses around expression [readability-redundant-parentheses]
12+
// CHECK-FIXES: (1 + 1);
13+
((((1 + 1))));
14+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
15+
// CHECK-MESSAGES: :[[@LINE-2]]:4: warning: redundant parentheses around expression [readability-redundant-parentheses]
16+
// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: redundant parentheses around expression [readability-redundant-parentheses]
17+
// CHECK-FIXES: (1 + 1);
18+
}
19+
20+
#define EXP (1 + 1)
21+
#define PAREN(e) (e)
22+
void parenExprWithMacro() {
23+
EXP; // 1
24+
(EXP); // 2
25+
((EXP)); // 3
26+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
27+
// CHECK-FIXES: (EXP); // 3
28+
PAREN((1));
29+
}
30+
31+
void constant() {
32+
(1);
33+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
34+
// CHECK-FIXES: 1;
35+
(1.0);
36+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
37+
// CHECK-FIXES: 1.0;
38+
(true);
39+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
40+
// CHECK-FIXES: true;
41+
(',');
42+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
43+
// CHECK-FIXES: ',';
44+
("v4");
45+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
46+
// CHECK-FIXES: "v4";
47+
(nullptr);
48+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
49+
// CHECK-FIXES: nullptr;
50+
}
51+
52+
void declRefExpr(int a) {
53+
(a);
54+
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant parentheses around expression [readability-redundant-parentheses]
55+
// CHECK-FIXES: a;
56+
}
57+
58+
void exceptions() {
59+
sizeof(1);
60+
alignof(2);
61+
alignof((3));
62+
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant parentheses around expression [readability-redundant-parentheses]
63+
// CHECK-FIXES: alignof(3);
64+
}

0 commit comments

Comments
 (0)