[clang-tools-extra] [llvm] [clang-tidy] Extend readability-redundant-parentheses to type (PR #196739)
Omkar Rasal via cfe-commits
cfe-commits at lists.llvm.org
Mon May 25 08:28:35 PDT 2026
https://github.com/cs25mtech12008 updated https://github.com/llvm/llvm-project/pull/196739
>From 696defd512a25ef3ab24a4ad21d02c4220817a1a Mon Sep 17 00:00:00 2001
From: cs25mtech12008 <cs25mtech12008 at iith.ac.in>
Date: Sat, 9 May 2026 23:07:30 +0530
Subject: [PATCH 1/5] added check for the parentheses declaration
---
.../readability/RedundantParenthesesCheck.cpp | 27 ++++++++++++++++---
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 9b3948a1c50c0..6d473ccf1c8df 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/TypeLoc.h"
#include "RedundantParenthesesCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
@@ -61,13 +62,31 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) {
hasParent(unaryExprOrTypeTraitExpr()))))
.bind("dup"),
this);
+
+ Finder->addMatcher(typeLoc(loc(parenType())).bind("parentheses-decl"), this);
}
void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup");
- diag(PE->getBeginLoc(), "redundant parentheses around expression")
- << FixItHint::CreateRemoval(PE->getLParen())
- << FixItHint::CreateRemoval(PE->getRParen());
+ if (const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup")) {
+
+ diag(PE->getBeginLoc(), "redundant parentheses around expression")
+ << FixItHint::CreateRemoval(PE->getLParen())
+ << FixItHint::CreateRemoval(PE->getRParen());
+ return ;
+ }
+
+ if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("parentheses-decl")) {
+ ParenTypeLoc ParenType = TL->getAs<ParenTypeLoc>();
+
+ if (ParenType.isNull())
+ return;
+
+ diag(ParenType.getLParenLoc(), "redundant parentheses in declaration")
+ << FixItHint::CreateRemoval(ParenType.getLParenLoc())
+ << FixItHint::CreateRemoval(ParenType.getRParenLoc());
+ return;
+ }
+
}
} // namespace clang::tidy::readability
>From b1eb370cc90287e2fa7984ec6c2264362774bd51 Mon Sep 17 00:00:00 2001
From: cs25mtech12008 <cs25mtech12008 at iith.ac.in>
Date: Sun, 10 May 2026 03:23:25 +0530
Subject: [PATCH 2/5] [clang-tidy] Addressed review comments for declaration
parentheses for readability
---
.../readability/RedundantParenthesesCheck.cpp | 15 +++++++++------
clang-tools-extra/docs/ReleaseNotes.rst | 3 +++
.../checks/readability/redundant-parentheses.rst | 6 ++++++
.../readability/redundant-parentheses.cpp | 12 ++++++++++++
4 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 6d473ccf1c8df..583f3d1941556 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -6,14 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/TypeLoc.h"
#include "RedundantParenthesesCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Lex/Lexer.h"
#include <cassert>
using namespace clang::ast_matchers;
@@ -68,25 +69,27 @@ void RedundantParenthesesCheck::registerMatchers(MatchFinder *Finder) {
void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *PE = Result.Nodes.getNodeAs<ParenExpr>("dup")) {
-
diag(PE->getBeginLoc(), "redundant parentheses around expression")
<< FixItHint::CreateRemoval(PE->getLParen())
<< FixItHint::CreateRemoval(PE->getRParen());
- return ;
+ return;
}
if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("parentheses-decl")) {
- ParenTypeLoc ParenType = TL->getAs<ParenTypeLoc>();
+ const auto ParenType = TL->getAs<ParenTypeLoc>();
if (ParenType.isNull())
return;
-
+ const QualType InnerLocType = ParenType.getInnerLoc().getType();
+ if (InnerLocType->isPointerType() || InnerLocType->isReferenceType() ||
+ InnerLocType->isMemberPointerType() || InnerLocType->isFunctionType() ||
+ InnerLocType->isArrayType())
+ return;
diag(ParenType.getLParenLoc(), "redundant parentheses in declaration")
<< FixItHint::CreateRemoval(ParenType.getLParenLoc())
<< FixItHint::CreateRemoval(ParenType.getRParenLoc());
return;
}
-
}
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 51251eacbcd5e..45fee6f634327 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -641,6 +641,9 @@ Changes in existing checks
note to suggest materializing the temporary range when iterating over temporary
range expressions or initializer lists, as reusing them directly could be unsafe.
+- Improved :doc:`readability-redundant-parentheses
+ <clang-tidy/checks/readability/redundant-parentheses>` check to diagnose
+ redundant parentheses in declarations such as int (x) and int (f(int(arg)))
Removed checks
^^^^^^^^^^^^^^
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 b9c50c5b59889..90ffcab679b23 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
@@ -40,3 +40,9 @@ Options
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.
+
+The check diagnoses redundant parentheses in declarations and keeps earlier changes as it is
+.. code-block:: c++
+
+ int (x); // becomes int x;
+ void f(int (arg)); // becomes void f(int arg);
\ No newline at end of file
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..11e46ae8a6a6f 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
@@ -121,3 +121,15 @@ void memberExpr() {
// CHECK-FIXES: if (foo.fooBar().z) {
}
}
+
+int (x);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-FIXES: int x;
+
+void f(int (arg));
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant parentheses in declaration
+// CHECK-FIXES: void f(int arg);
+
+//Negative Test cases for redundant parentheses in declaration
+int (*functionPtr)(int);
+int (*array[2])(int);
>From 1ca6a811f1df2442101a568ac1af72eb37692d58 Mon Sep 17 00:00:00 2001
From: cs25mtech12008 <cs25mtech12008 at iith.ac.in>
Date: Mon, 11 May 2026 21:09:11 +0530
Subject: [PATCH 3/5] [clang-tidy] Address review feedback for redundant
parentheses
---
.../readability/RedundantParenthesesCheck.cpp | 18 +++----
clang-tools-extra/docs/ReleaseNotes.rst | 8 +--
.../readability/redundant-parentheses.rst | 7 +--
.../readability/redundant-parentheses.cpp | 49 ++++++++++++++++++-
4 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 583f3d1941556..ba08b105f2ed3 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -74,20 +74,20 @@ void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateRemoval(PE->getRParen());
return;
}
-
if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("parentheses-decl")) {
const auto ParenType = TL->getAs<ParenTypeLoc>();
-
if (ParenType.isNull())
return;
- const QualType InnerLocType = ParenType.getInnerLoc().getType();
- if (InnerLocType->isPointerType() || InnerLocType->isReferenceType() ||
- InnerLocType->isMemberPointerType() || InnerLocType->isFunctionType() ||
- InnerLocType->isArrayType())
+ SourceLocation LParen = ParenType.getLParenLoc();
+ SourceLocation RParen = ParenType.getRParenLoc();
+ if (LParen.isMacroID() || RParen.isMacroID())
+ return;
+ const TypeLoc Inner = ParenType.getInnerLoc();
+ if (Inner.getType()->isFunctionType() ||
+ Inner.getType()->isFunctionPointerType())
return;
- diag(ParenType.getLParenLoc(), "redundant parentheses in declaration")
- << FixItHint::CreateRemoval(ParenType.getLParenLoc())
- << FixItHint::CreateRemoval(ParenType.getRParenLoc());
+ diag(LParen, "redundant parentheses in declaration")
+ << FixItHint::CreateRemoval(LParen) << FixItHint::CreateRemoval(RParen);
return;
}
}
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 45fee6f634327..e4805ee10ca99 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -617,6 +617,11 @@ Changes in existing checks
`IgnoreMacros` option to suppress warnings when the initializer involves
macros that may expand differently in other configurations.
+- Improved :doc:`readability-redundant-parentheses
+ <clang-tidy/checks/readability/redundant-parentheses>` check to diagnose
+ redundant parentheses in declarations such as ``int (x)`` and
+ ``int f(int (arg))``.
+
- Improved :doc:`readability-redundant-preprocessor
<clang-tidy/checks/readability/redundant-preprocessor>` check by fixing a
false positive for nested ``#if`` directives using different builtin
@@ -641,9 +646,6 @@ Changes in existing checks
note to suggest materializing the temporary range when iterating over temporary
range expressions or initializer lists, as reusing them directly could be unsafe.
-- Improved :doc:`readability-redundant-parentheses
- <clang-tidy/checks/readability/redundant-parentheses>` check to diagnose
- redundant parentheses in declarations such as int (x) and int (f(int(arg)))
Removed checks
^^^^^^^^^^^^^^
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 90ffcab679b23..54dcbd23bd2db 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
@@ -41,8 +41,9 @@ Options
macro. For example, ``std::max`` and ``max`` macro. A workaround to distinguish
them is adding parentheses around functions to prevent function-like macro.
-The check diagnoses redundant parentheses in declarations and keeps earlier changes as it is
+The check also diagnoses redundant parentheses in simple declarations:
+
.. code-block:: c++
- int (x); // becomes int x;
- void f(int (arg)); // becomes void f(int arg);
\ No newline at end of file
+ int (x); // becomes int x;
+ void f(int (arg)); // becomes void f(int arg);
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 11e46ae8a6a6f..847e59bf5aabe 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
@@ -130,6 +130,51 @@ void f(int (arg));
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant parentheses in declaration
// CHECK-FIXES: void f(int arg);
-//Negative Test cases for redundant parentheses in declaration
+int ((nestedX));
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: redundant parentheses in declaration
+// CHECK-FIXES: int nestedX;
+
+void nestedParam(int ((arg)));
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-2]]:23: warning: redundant parentheses in declaration
+// CHECK-FIXES: void nestedParam(int arg);
+
+int (&referenceVar) = x;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-FIXES: int &referenceVar = x;
+
+struct S {};
+int (S::*memberPtr);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-FIXES: int S::*memberPtr;
+
+int (arrayVar)[2];
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-FIXES: int arrayVar[2];
+
+template <class T>
+void templatedParam(T (arg));
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant parentheses in declaration
+// CHECK-FIXES: void templatedParam(T arg);
+
+template <class T>
+struct TemplateStruct {
+ T (member);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-FIXES: T member;
+};
+
+// Negative cases.
int (*functionPtr)(int);
-int (*array[2])(int);
+void (*callback)(int);
+int (*arrayPtr[2])(int);
+#define DECL_WITH_PARENS(name) int (name)
+DECL_WITH_PARENS(macroVar);
+#define PAREN_NAME(name) (name)
+int PAREN_NAME(macroName);
+using AliasName = int;
+void instantiateTemplates() {
+ templatedParam<int>(0);
+ TemplateStruct<int> s;
+}
\ No newline at end of file
>From f126deed46a6d46e726edf7c0e4b61e51e452a15 Mon Sep 17 00:00:00 2001
From: cs25mtech12008 <cs25mtech12008 at iith.ac.in>
Date: Thu, 21 May 2026 22:58:46 +0530
Subject: [PATCH 4/5] [clang-tidy] Add tests and change in message
---
.../readability/RedundantParenthesesCheck.cpp | 9 +++---
.../readability/redundant-parentheses.cpp | 28 +++++++++++--------
2 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index ba08b105f2ed3..428e2353100f5 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -76,17 +76,16 @@ void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
}
if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("parentheses-decl")) {
const auto ParenType = TL->getAs<ParenTypeLoc>();
- if (ParenType.isNull())
- return;
- SourceLocation LParen = ParenType.getLParenLoc();
- SourceLocation RParen = ParenType.getRParenLoc();
+ assert(!ParenType.isNull() && "Expected ParenTypeLoc");
+ const SourceLocation LParen = ParenType.getLParenLoc();
+ const SourceLocation RParen = ParenType.getRParenLoc();
if (LParen.isMacroID() || RParen.isMacroID())
return;
const TypeLoc Inner = ParenType.getInnerLoc();
if (Inner.getType()->isFunctionType() ||
Inner.getType()->isFunctionPointerType())
return;
- diag(LParen, "redundant parentheses in declaration")
+ diag(LParen, "redundant parentheses in type")
<< FixItHint::CreateRemoval(LParen) << FixItHint::CreateRemoval(RParen);
return;
}
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 847e59bf5aabe..eafa48fd79841 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
@@ -123,45 +123,45 @@ void memberExpr() {
}
int (x);
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
// CHECK-FIXES: int x;
void f(int (arg));
-// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant parentheses in type
// CHECK-FIXES: void f(int arg);
int ((nestedX));
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
-// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
+// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: redundant parentheses in type
// CHECK-FIXES: int nestedX;
void nestedParam(int ((arg)));
-// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant parentheses in declaration
-// CHECK-MESSAGES: :[[@LINE-2]]:23: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant parentheses in type
+// CHECK-MESSAGES: :[[@LINE-2]]:23: warning: redundant parentheses in type
// CHECK-FIXES: void nestedParam(int arg);
int (&referenceVar) = x;
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
// CHECK-FIXES: int &referenceVar = x;
struct S {};
int (S::*memberPtr);
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
// CHECK-FIXES: int S::*memberPtr;
int (arrayVar)[2];
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
// CHECK-FIXES: int arrayVar[2];
template <class T>
void templatedParam(T (arg));
-// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant parentheses in type
// CHECK-FIXES: void templatedParam(T arg);
template <class T>
struct TemplateStruct {
T (member);
-// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in declaration
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
// CHECK-FIXES: T member;
};
@@ -177,4 +177,8 @@ using AliasName = int;
void instantiateTemplates() {
templatedParam<int>(0);
TemplateStruct<int> s;
-}
\ No newline at end of file
+}
+using Fn = void(int);
+Fn (*funcPtr);
+void (func)(int);
+int (*ptr)(int);
>From 2f495a8e29553edeeaccfcd7f489aca4a172bcb7 Mon Sep 17 00:00:00 2001
From: cs25mtech12008 <cs25mtech12008 at iith.ac.in>
Date: Mon, 25 May 2026 17:36:34 +0530
Subject: [PATCH 5/5] [clang-tidy] Address review comments for declaration
parentheses
---
.github/workflows/release-binaries.yml | 211 ++++++------------
.../readability/RedundantParenthesesCheck.cpp | 22 +-
.../readability/redundant-parentheses.cpp | 19 +-
3 files changed, 111 insertions(+), 141 deletions(-)
diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml
index b85083cd91d5f..104d37db8a28d 100644
--- a/.github/workflows/release-binaries.yml
+++ b/.github/workflows/release-binaries.yml
@@ -39,12 +39,9 @@ on:
required: true
type: string
secrets:
- LLVM_TOKEN_GENERATOR_CLIENT_ID:
- description: "Client ID for our GitHub App we use for generating access tokens."
- required: true
- LLVM_TOKEN_GENERATOR_PRIVATE_KEY:
- description: "Private key for our GitHub App we use for generating access tokens."
- required: true
+ RELEASE_TASKS_USER_TOKEN:
+ description: "Secret used to check user permissions."
+ required: false
permissions:
@@ -53,9 +50,6 @@ permissions:
jobs:
prepare:
name: Prepare to build binaries
- environment:
- deployment: false
- name: ${{ case( github.event_name == 'pull_request', null, 'release') }}
runs-on: ${{ inputs.runs-on }}
if: github.repository_owner == 'llvm'
outputs:
@@ -68,31 +62,33 @@ jobs:
release-binary-filename: ${{ steps.vars.outputs.release-binary-filename }}
build-runs-on: ${{ steps.vars.outputs.build-runs-on }}
test-runs-on: ${{ steps.vars.outputs.build-runs-on }}
- attestation-name: ${{ steps.vars.outputs.attestation-name }}
steps:
- - name: Checkout LLVM
- uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ # It's good practice to use setup-python, but this is also required on macos-14
+ # due to https://github.com/actions/runner-images/issues/10385
+ - uses: actions/setup-python at e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
- persist-credentials: false
+ python-version: '3.14'
+
+ - name: Checkout LLVM
+ uses: actions/checkout at 1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
+
+ - name: Install Dependencies
+ shell: bash
+ run: |
+ pip install --require-hashes -r ./llvm/utils/git/requirements.txt
- name: Check Permissions
if: github.event_name != 'pull_request'
- uses: ./.github/workflows/require-release-manager
- with:
- LLVM_TOKEN_GENERATOR_CLIENT_ID: ${{ secrets.LLVM_TOKEN_GENERATOR_CLIENT_ID }}
- LLVM_TOKEN_GENERATOR_PRIVATE_KEY: ${{ secrets.LLVM_TOKEN_GENERATOR_PRIVATE_KEY }}
-
- # The name of the Windows binaries uses the version from source, so we need
- # to fetch it here.
- - id: version-from-source
- if: runner.os == 'Windows'
- uses: ./.github/workflows/get-llvm-version
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ USER_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }}
+ shell: bash
+ run: |
+ ./llvm/utils/release/./github-upload-release.py --token "$GITHUB_TOKEN" --user "$GITHUB_ACTOR" --user-token "$USER_TOKEN" check-permissions
- name: Collect Variables
id: vars
- env:
- LLVM_VERSION_FROM_SOURCE: ${{ steps.version-from-source.outputs.full-no-suffix }}
shell: bash
# In order for the test-release.sh script to run correctly, the LLVM
# source needs to be at the following location relative to the build dir:
@@ -108,11 +104,7 @@ jobs:
release_version="$trimmed"
ref="llvmorg-$release_version"
else
- if [ "$RUNNER_OS" = "Windows" ]; then
- release_version="$LLVM_VERSION_FROM_SOURCE"
- else
- release_version="${{ (github.event_name == 'pull_request' && format('PR{0}', github.event.pull_request.number)) || 'CI'}}-$GITHUB_SHA"
- fi
+ release_version="${{ (github.event_name == 'pull_request' && format('PR{0}', github.event.pull_request.number)) || 'CI'}}-$GITHUB_SHA"
ref="$GITHUB_SHA"
fi
if [ -n "${{ inputs.upload }}" ]; then
@@ -124,19 +116,7 @@ jobs:
echo "ref=$ref" >> $GITHUB_OUTPUT
echo "upload=$upload" >> $GITHUB_OUTPUT
- if [ "$RUNNER_OS" = "Windows" ]; then
- case $RUNNER_ARCH in
- "X64" )
- tar_arch="x86_64"
- ;;
- "ARM64" )
- tar_arch="aarch64"
- ;;
- esac
- release_binary_basename="clang+llvm-$release_version-$tar_arch-pc-windows-msvc"
- else
- release_binary_basename="LLVM-$release_version-$RUNNER_OS-$RUNNER_ARCH"
- fi
+ release_binary_basename="LLVM-$release_version-$RUNNER_OS-$RUNNER_ARCH"
echo "release-binary-basename=$release_binary_basename" >> $GITHUB_OUTPUT
echo "release-binary-filename=$release_binary_basename.tar.xz" >> $GITHUB_OUTPUT
@@ -159,18 +139,10 @@ jobs:
fi
case "${{ inputs.runs-on }}" in
- ubuntu-22.04* | windows-2022)
+ ubuntu-22.04*)
build_runs_on="depot-${{ inputs.runs-on }}-16"
test_runs_on=$build_runs_on
;;
- windows-11-arm)
- if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "schedule" ]; then
- build_runs_on="${{ inputs.runs-on }}"
- else
- build_runs_on="windows-11-arm-16core"
- fi
- test_runs_on=$build_runs_on
- ;;
macos-14)
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
build_runs_on="${{ inputs.runs-on }}"
@@ -203,40 +175,17 @@ jobs:
echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT
echo "build-runs-on=$build_runs_on" >> $GITHUB_OUTPUT
echo "test-runs-on=$test_runs_on" >> $GITHUB_OUTPUT
- echo "attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-binary-attestation" >> $GITHUB_OUTPUT
build-release-package:
name: "Build Release Package"
needs: prepare
if: github.repository_owner == 'llvm'
runs-on: ${{ needs.prepare.outputs.build-runs-on }}
- outputs:
- digest: ${{ steps.digest.outputs.digest }}
- artifact-id: ${{ steps.artifact-upload.outputs.artifact-id }}
steps:
- # We need to hard code the python library path for Windows, so in order
- # to do that we need to specify a specific python version. It's also
- # good practice to do this on other OSes so the version of python doesn't
- # get changed unexpectedly.
- - uses: actions/setup-python at a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- with:
- python-version: '3.11.9'
-
- # For some reason this is needed on Windows or else the build system can't find python3.lib.
- - name: Setup Python library path
- if: runner.os == 'Windows'
- run: |
- echo "LIB=$env:LIB;C:\hostedtoolcache\windows\Python\3.11.9\$($env:RUNNER_ARCH.ToLower())\libs" >> $env:GITHUB_ENV
-
- - name: Setup crlf
- if: runner.os == 'Windows'
- run: |
- git config --global core.autocrlf false
- name: Checkout LLVM
- uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout at 1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
- persist-credentials: false
ref: ${{ needs.prepare.outputs.ref }}
- name: Set Build Prefix
@@ -250,9 +199,8 @@ jobs:
fi
echo "build-prefix=$build_prefix" >> $GITHUB_OUTPUT
- - name: Configure Linux/MacOS
+ - name: Configure
id: build
- if: runner.os != 'Windows'
shell: bash
run: |
# There were some issues on the ARM64 MacOS runners with trying to build x86 object,
@@ -261,60 +209,23 @@ jobs:
${{ needs.prepare.outputs.target-cmake-flags }} \
-C clang/cmake/caches/Release.cmake
- - name: Build Linux/MacOS
- if: runner.os != 'Windows'
+ - name: Build
shell: bash
run: |
ninja -v -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-package
release_dir=`find ${{ steps.setup-stage.outputs.build-prefix }}/build -iname 'stage2-bins'`
mv $release_dir/${{ needs.prepare.outputs.release-binary-filename }} .
-
- - name: Build Windows
- id: build-windows
- if: runner.os == 'Windows'
- env:
- LLVM_VERSION: ${{ needs.prepare.outputs.release-version }}
- run: |
- subst S: ${{ github.workspace }}
- cd S:\llvm\utils\release\
- .\build_llvm_release.bat "--$($env:RUNNER_ARCH.ToLower())" --version $env:LLVM_VERSION --local-python --skip-checkout
- $installer = (Get-ChildItem -Recurse -Filter "*.exe" | Select-Object -First 1).fullName
- $tarball = (Get-ChildItem -Recurse -Filter "*.tar.xz" | Select-Object -First 1).fullName
- # Move installer to top-level directory so it is easier to upload.
- mv $installer $env:GITHUB_WORKSPACE
- mv $tarball $env:GITHUB_WORKSPACE
- echo "windows-installer-filename=$(Split-Path -Path $installer -Leaf)" >> $env:GITHUB_OUTPUT
-
- - name: Generate sha256 digest for binaries
- id: digest
- shell: bash
- env:
- RELEASE_BINARY_FILENAME: ${{ needs.prepare.outputs.release-binary-filename }}
- # This will be empty on non-Windows builds.
- WINDOWS_INSTALLER_FILENAME: ${{ steps.build-windows.outputs.windows-installer-filename }}
- run: |
- if [ "$RUNNER_OS" = "macOS" ]; then
- # Mac runners don't have sha256sum.
- sha256sum="shasum -a 256"
- else
- sha256sum="sha256sum"
- fi
- echo "digest=$(cat $WINDOWS_INSTALLER_FILENAME $RELEASE_BINARY_FILENAME | $sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
-
- - uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
- id: artifact-upload
+
+ - uses: actions/upload-artifact at 330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: ${{ runner.os }}-${{ runner.arch }}-release-binary
# Due to path differences on Windows when running in bash vs running on node,
# we need to search for files in the current workspace.
- # The steps.build-windows.* variables will be empty on Linux/MacOS.
path: |
${{ needs.prepare.outputs.release-binary-filename }}
- ${{ steps.build-windows.outputs.windows-installer-filename }}
- name: Run Tests
# These almost always fail so don't let them fail the build and prevent the uploads.
- if : runner.os != 'Windows'
continue-on-error: true
run: |
ninja -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-check-all
@@ -325,7 +236,8 @@ jobs:
- prepare
- build-release-package
if: >-
- github.event_name != 'pull_request'
+ github.event_name != 'pull_request' &&
+ needs.prepare.outputs.upload == 'true'
runs-on: ubuntu-24.04
permissions:
contents: write # For release uploads
@@ -333,22 +245,45 @@ jobs:
attestations: write # For artifact attestations
steps:
- - name: Checkout Release Scripts
- uses: actions/checkout at de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- with:
- persist-credentials: false
- sparse-checkout: |
- .github/workflows/upload-release-artifact
- llvm/utils/release/github-upload-release.py
- llvm/utils/git/requirements.txt
- sparse-checkout-cone-mode: false
-
- - name: Upload Artifacts
- uses: ./.github/workflows/upload-release-artifact
- with:
- release-version: ${{ needs.prepare.outputs.release-version }}
- artifact-id: ${{ needs.build-release-package.outputs.artifact-id }}
- attestation-name: ${{ needs.prepare.outputs.attestation-name }}
- digest: ${{ needs.build-release-package.outputs.digest }}
- upload: ${{ needs.prepare.outputs.upload }}
- user-token: ${{ secrets.RELEASE_TASKS_USER_TOKEN }}
+ - name: Checkout Release Scripts
+ uses: actions/checkout at 1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
+ with:
+ sparse-checkout: |
+ llvm/utils/release/github-upload-release.py
+ llvm/utils/git/requirements.txt
+ sparse-checkout-cone-mode: false
+
+ - name: 'Download artifact'
+ uses: actions/download-artifact at 018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
+ with:
+ pattern: '*-release-binary'
+ merge-multiple: true
+
+ - name: Attest Build Provenance
+ id: provenance
+ uses: actions/attest-build-provenance at 977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
+ with:
+ subject-path: ${{ needs.prepare.outputs.release-binary-filename }}
+
+ - name: Rename attestation file
+ run:
+ mv ${{ steps.provenance.outputs.bundle-path }} ${{ needs.prepare.outputs.release-binary-filename }}.jsonl
+
+ - name: Upload Build Provenance
+ uses: actions/upload-artifact at 330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
+ with:
+ name: ${{ needs.prepare.outputs.release-binary-filename }}-attestation
+ path: ${{ needs.prepare.outputs.release-binary-filename }}.jsonl
+
+ - name: Install Python Requirements
+ run: |
+ pip install --require-hashes -r ./llvm/utils/git/requirements.txt
+
+ - name: Upload Release
+ shell: bash
+ run: |
+ ./llvm/utils/release/github-upload-release.py \
+ --token ${{ github.token }} \
+ --release ${{ needs.prepare.outputs.release-version }} \
+ upload \
+ --files ${{ needs.prepare.outputs.release-binary-filename }}*
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
index 428e2353100f5..3b265104faf83 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantParenthesesCheck.cpp
@@ -15,6 +15,8 @@
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
using namespace clang::ast_matchers;
@@ -74,6 +76,7 @@ void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateRemoval(PE->getRParen());
return;
}
+
if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("parentheses-decl")) {
const auto ParenType = TL->getAs<ParenTypeLoc>();
assert(!ParenType.isNull() && "Expected ParenTypeLoc");
@@ -81,9 +84,26 @@ void RedundantParenthesesCheck::check(const MatchFinder::MatchResult &Result) {
const SourceLocation RParen = ParenType.getRParenLoc();
if (LParen.isMacroID() || RParen.isMacroID())
return;
+ const auto Text = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(SourceRange(LParen, RParen)),
+ *Result.SourceManager, getLangOpts());
const TypeLoc Inner = ParenType.getInnerLoc();
+ if (Text.starts_with("(&") && Inner.getType()->isArrayType())
+ return;
+ if (Inner.getType()->isFunctionType()) {
+ const auto Text = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(SourceRange(LParen, RParen)),
+ *Result.SourceManager, getLangOpts());
+ if (!Text.starts_with("(*") && !Text.contains("::*")) {
+ diag(LParen, "redundant parentheses in type")
+ << FixItHint::CreateRemoval(LParen)
+ << FixItHint::CreateRemoval(RParen);
+ return;
+ }
+ }
if (Inner.getType()->isFunctionType() ||
- Inner.getType()->isFunctionPointerType())
+ Inner.getType()->isFunctionPointerType() ||
+ Inner.getType()->isMemberFunctionPointerType())
return;
diag(LParen, "redundant parentheses in type")
<< FixItHint::CreateRemoval(LParen) << FixItHint::CreateRemoval(RParen);
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 eafa48fd79841..6d1c27eaa560d 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
@@ -153,6 +153,18 @@ int (arrayVar)[2];
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant parentheses in type
// CHECK-FIXES: int arrayVar[2];
+const int (cx) = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant parentheses in type
+// CHECK-FIXES: const int cx = 0;
+
+typedef int (TypedefName);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant parentheses in type
+// CHECK-FIXES: typedef int TypedefName;
+
+void (func)(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant parentheses in type
+// CHECK-FIXES: void func(int);
+
template <class T>
void templatedParam(T (arg));
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant parentheses in type
@@ -165,7 +177,6 @@ struct TemplateStruct {
// CHECK-FIXES: T member;
};
-// Negative cases.
int (*functionPtr)(int);
void (*callback)(int);
int (*arrayPtr[2])(int);
@@ -180,5 +191,9 @@ void instantiateTemplates() {
}
using Fn = void(int);
Fn (*funcPtr);
-void (func)(int);
int (*ptr)(int);
+struct T {
+void method(int);
+};
+void (T::*memberFunctionPtr)(int);
+int (&arrayRef)[2] = arrayVar;
More information about the cfe-commits
mailing list