[clang-tools-extra] [clang-tidy] Adds readability-redundant-const check (PR #189733)
Berkay Sahin via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 3 13:26:17 PDT 2026
https://github.com/berkaysahiin updated https://github.com/llvm/llvm-project/pull/189733
>From 8343df89f949fa30c75cbdd09130b08649577dee Mon Sep 17 00:00:00 2001
From: Berkay Sahin <berkaysahindev at gmail.com>
Date: Tue, 31 Mar 2026 22:20:46 +0300
Subject: [PATCH 1/6] [clang-tidy] Adds readability-redundant-const check
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../readability/ReadabilityTidyModule.cpp | 3 +
.../readability/RedundantConstCheck.cpp | 106 ++++++++++++
.../readability/RedundantConstCheck.h | 31 ++++
clang-tools-extra/docs/ReleaseNotes.rst | 5 +
.../docs/clang-tidy/checks/list.rst | 1 +
.../checks/readability/redundant-const.rst | 49 ++++++
.../checkers/readability/redundant-const.cpp | 156 ++++++++++++++++++
8 files changed, 352 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantConstCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 686e7c19d650b..95fb26b1fa7ac 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -41,6 +41,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
ReadabilityTidyModule.cpp
RedundantAccessSpecifiersCheck.cpp
RedundantCastingCheck.cpp
+ RedundantConstCheck.cpp
RedundantControlFlowCheck.cpp
RedundantDeclarationCheck.cpp
RedundantFunctionPtrDereferenceCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 8e9e00b23c84a..090bc073cab93 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -42,6 +42,7 @@
#include "QualifiedAutoCheck.h"
#include "RedundantAccessSpecifiersCheck.h"
#include "RedundantCastingCheck.h"
+#include "RedundantConstCheck.h"
#include "RedundantControlFlowCheck.h"
#include "RedundantDeclarationCheck.h"
#include "RedundantFunctionPtrDereferenceCheck.h"
@@ -141,6 +142,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-redundant-access-specifiers");
CheckFactories.registerCheck<RedundantCastingCheck>(
"readability-redundant-casting");
+ CheckFactories.registerCheck<RedundantConstCheck>(
+ "readability-redundant-const");
CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>(
"readability-redundant-function-ptr-dereference");
CheckFactories.registerCheck<RedundantMemberInitCheck>(
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
new file mode 100644
index 0000000000000..1956f9a78e495
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 "RedundantConstCheck.h"
+#include "../utils/LexerUtils.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include <optional>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+static const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl>
+ varTemplateDecl;
+
+static std::optional<Token>
+findConstToRemove(const VarDecl *VD, const MatchFinder::MatchResult &Result) {
+ const SourceManager &SM = *Result.SourceManager;
+
+ const SourceLocation NameBeginLoc = VD->getQualifier()
+ ? VD->getQualifierLoc().getBeginLoc()
+ : VD->getLocation();
+
+ const bool IsPointer = VD->getType()->isPointerType() ||
+ VD->getType()->isNullPtrType() ||
+ VD->getType()->isMemberPointerType();
+
+ const auto ConstSearchStartLoc = [&]() -> std::optional<SourceLocation> {
+ if (!IsPointer)
+ return VD->getBeginLoc();
+
+ SourceLocation StarLoc = utils::lexer::findPreviousTokenKind(
+ NameBeginLoc, SM, Result.Context->getLangOpts(), tok::star);
+
+ if (StarLoc.isValid())
+ return StarLoc;
+
+ // We know it is a pointer but cannot find the start token.
+ // This can happen when either type is aliased or `auto` was used.
+ // e.g: constexpr const auto const str = "hello";
+ // In cases like this, clang analyzer already warns about the use of const
+ // as duplicate, so we can safely ignore these cases.
+
+ return std::nullopt;
+ }();
+
+ if (!ConstSearchStartLoc || !ConstSearchStartLoc->isValid())
+ return std::nullopt;
+
+ const CharSourceRange FileRange = Lexer::makeFileCharRange(
+ CharSourceRange::getCharRange(*ConstSearchStartLoc, NameBeginLoc), SM,
+ Result.Context->getLangOpts());
+
+ if (!FileRange.isValid())
+ return std::nullopt;
+
+ return utils::lexer::getQualifyingToken(tok::kw_const, FileRange,
+ *Result.Context, SM);
+}
+
+RedundantConstCheck::RedundantConstCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+
+void RedundantConstCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ varDecl(isConstexpr(), unless(anyOf(hasAncestor(varTemplateDecl()),
+ hasType(referenceType()))))
+ .bind("var_decl"),
+ this);
+}
+
+void RedundantConstCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var_decl");
+
+ // Since we cannot tell the difference between `constexpr const` and
+ // `constexpr` from the AST only, if we cannot find the actual `const` token,
+ // we cannot do anything
+ const std::optional<Token> Tok = findConstToRemove(VD, Result);
+ if (!Tok)
+ return;
+
+ const auto ConstRange =
+ CharSourceRange::getCharRange(Tok->getLocation(), Tok->getEndLoc());
+ diag(Tok->getLocation(),
+ "redundant 'const' in constexpr variable declaration")
+ << ConstRange << FixItHint::CreateRemoval(ConstRange);
+}
+
+bool RedundantConstCheck::isLanguageVersionSupported(
+ const LangOptions &LangOpts) const {
+ return LangOpts.CPlusPlus11;
+}
+
+std::optional<TraversalKind>
+RedundantConstCheck::getCheckTraversalKind() const {
+ return TK_IgnoreUnlessSpelledInSource;
+}
+
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.h
new file mode 100644
index 0000000000000..882fe4f036f03
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.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_REDUNDANTCONSTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTCONSTCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// Detects redundant `const` specifiers on variable declarations.
+//
+/// For the user-facing documentation see:
+/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-const.html
+class RedundantConstCheck : public ClangTidyCheck {
+public:
+ RedundantConstCheck(StringRef Name, ClangTidyContext *Context);
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override;
+ std::optional<TraversalKind> getCheckTraversalKind() const override;
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTCONSTCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 97b2ffdd9557b..3312beebcff55 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -163,6 +163,11 @@ New checks
Finds redundant identity type aliases that re-expose a qualified name and can
be replaced with a ``using`` declaration.
+- New :doc:`readability-redundant-const
+ <clang-tidy/checks/readability/redundant-const>` check.
+
+ Detects redundant ``const`` specifiers on variable declarations.
+
- New :doc:`readability-trailing-comma
<clang-tidy/checks/readability/trailing-comma>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index ceab1e9414951..427babef23c9b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -410,6 +410,7 @@ Clang-Tidy Checks
:doc:`readability-qualified-auto <readability/qualified-auto>`, "Yes"
:doc:`readability-redundant-access-specifiers <readability/redundant-access-specifiers>`, "Yes"
:doc:`readability-redundant-casting <readability/redundant-casting>`, "Yes"
+ :doc:`readability-redundant-const <readability/redundant-const>`, "Yes"
:doc:`readability-redundant-control-flow <readability/redundant-control-flow>`, "Yes"
:doc:`readability-redundant-declaration <readability/redundant-declaration>`, "Yes"
:doc:`readability-redundant-function-ptr-dereference <readability/redundant-function-ptr-dereference>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
new file mode 100644
index 0000000000000..ed6957f21e312
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
@@ -0,0 +1,49 @@
+.. title:: clang-tidy - readability-redundant-const
+
+readability-redundant-const
+=============================
+
+Detects redundant ``const`` specifiers on variable declarations.
+
+Examples:
+
+.. code-block:: c++
+
+ // Finds:
+ constexpr const int var = {}; // redundant use of `const`
+ // replaced by:
+ constexpr int var = {};
+
+ // Finds:
+ constexpr const int arr[] = {}; // redundant use of `const`
+ // replaced by:
+ constexpr int arr[] = {};
+
+In the examples above, use of ``const`` is redundant since ``constexpr``
+variables are implicitly ``const``.
+
+The check also analyzes pointers:
+
+.. code-block:: c++
+
+ // Finds:
+ constexpr int* const ptr = nullptr; // redundant use of `const`
+ // replaced by:
+ constexpr int* ptr = nullptr;
+
+ // Finds:
+ constexpr int (*const func)(int) = nullptr; // redundant use of `const`
+ // replaced by:
+ constexpr int (*func)(int) = nullptr;
+
+ // Finds:
+ constexpr const char* const greet = "hi"; // redundant use of `const`
+ // replaced by:
+ constexpr const char* greet = "hi";
+
+ // Note that `constexpr` only makes the pointer const but not the pointee.
+ // Thus, this usage is *not* redundant.
+ constexpr const char* ok = "ok"; // OK
+
+
+Requires C++11 or above.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
new file mode 100644
index 0000000000000..6a49e9837b414
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
@@ -0,0 +1,156 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-const %t --
+
+struct Foo {};
+
+// Simple allowed usages, nothing to warn
+constexpr int n1 = 10;
+const int n2 = 20;
+constexpr Foo n3 = {};
+
+constexpr const int p1 = 10;
+// CHECK-MESSAGES: [[@LINE-1]]:11: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr int p1 = 10;
+
+const constexpr int p2 = 20;
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr int p2 = 20;
+
+static const constexpr int p3 = 20;
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: static constexpr int p3 = 20;
+
+constexpr const Foo p4 = {};
+// CHECK-MESSAGES: [[@LINE-1]]:11: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr Foo p4 = {};
+
+// Since constexpr makes only the pointer const, this usage is not redundant.
+constexpr const char* n4 = "hello";
+
+constexpr const char* const n5 = "hello";
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr const char* n5 = "hello";
+
+// Since T might be a pointer type, we don't warn on this.
+template<typename T>
+const constexpr T n6 = {};
+
+constexpr const int* n7 = n6<int*>;
+
+const constexpr double p5 = n6<double>;
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr double p5 = n6<double>;
+
+constexpr const int* const p6 = n6<int*>;
+// CHECK-MESSAGES: [[@LINE-1]]:22: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr const int* p6 = n6<int*>;
+
+void f() {
+ constexpr Foo n1 = {};
+ const Foo n2 = {};
+
+ const constexpr Foo p1 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant 'const' in constexpr variable declaration
+ // CHECK-FIXES: constexpr Foo p1 = {};
+
+ static const constexpr Foo p2 = {};
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant 'const' in constexpr variable declaration
+ // CHECK-FIXES: static constexpr Foo p2 = {};
+}
+
+struct Config {
+ static const constexpr bool p = false;
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant 'const' in constexpr variable declaration
+ // CHECK-FIXES: static constexpr bool p = false;
+};
+
+template <typename T>
+class Templated {
+ static const constexpr int size = 10;
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant 'const' in constexpr variable declaration
+ // CHECK-FIXES: static constexpr int size = 10;
+ int data[size];
+};
+
+constexpr Templated<int> b{};
+
+template <int N>
+struct Templated2 {
+ static const constexpr int size = N;
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant 'const' in constexpr variable declaration
+ // CHECK-FIXES: static constexpr int size = N;
+ int data[size];
+};
+
+static constexpr int n8[] = {0, 1, 4, 9, 16};
+
+constexpr const int p7[] = {0, 1, 4, 9, 16};
+// CHECK-MESSAGES: [[@LINE-1]]:11: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr int p7[] = {0, 1, 4, 9, 16};
+
+constexpr int square(int n) { return n * n; }
+
+const constexpr int p8 = square(10);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr int p8 = square(10);
+
+constexpr int n9 = square(5);
+
+constexpr Foo** n10 = nullptr;
+
+constexpr Foo* const* n11 = nullptr;
+
+constexpr Foo* const* const p9 = nullptr;
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr Foo* const* p9 = nullptr;
+
+constexpr const Foo* const* const p10 = nullptr;
+// CHECK-MESSAGES: [[@LINE-1]]:29: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr const Foo* const* p10 = nullptr;
+
+constexpr const int (*n12)[10] = nullptr;
+
+constexpr const int (*const p11)[10] = nullptr;
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr const int (*p11)[10] = nullptr;
+
+constexpr int (*n13)(int) = nullptr;
+
+constexpr int (*const p12)(int) = nullptr;
+// CHECK-MESSAGES: [[@LINE-1]]:17: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr int (*p12)(int) = nullptr;
+
+struct Bar {
+ int x, y;
+ int sum() { return x + y; }
+};
+
+// Pointer to data member
+constexpr const int Bar::*n14 = &Bar::x;
+
+// Pointer to data member
+constexpr const int Bar::* const p13 = &Bar::x;
+// CHECK-MESSAGES: [[@LINE-1]]:28: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr const int Bar::* p13 = &Bar::x;
+
+// Pointer to member function
+constexpr int (Bar::*n15)() = &Bar::sum;
+
+// Pointer to member function
+constexpr int (Bar::* const p14)() = &Bar::sum;
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: constexpr int (Bar::* p14)() = &Bar::sum;
+
+#define CONSTEXPR constexpr
+
+CONSTEXPR Foo n16 = {};
+
+CONSTEXPR const Foo p15 = {};
+// CHECK-MESSAGES: [[@LINE-1]]:11: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: CONSTEXPR Foo p15 = {};
+
+const CONSTEXPR Foo p16 = {};
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: redundant 'const' in constexpr variable declaration
+// CHECK-FIXES: CONSTEXPR Foo p16 = {};
+
+// OK for references
+constexpr const Foo& n17 = p15;
>From 26d9a50843e015ec17b6d5aaadb62b18142d58b6 Mon Sep 17 00:00:00 2001
From: Berkay Sahin <berkaysahindev at gmail.com>
Date: Tue, 31 Mar 2026 22:56:39 +0300
Subject: [PATCH 2/6] [clang-tidy] fix linter
---
.../clang-tidy/readability/RedundantConstCheck.cpp | 4 ++--
clang-tools-extra/docs/ReleaseNotes.rst | 10 +++++-----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
index 1956f9a78e495..421143db7b2b7 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
@@ -17,7 +17,7 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
static const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl>
- varTemplateDecl;
+ VarTemplateDecl;
static std::optional<Token>
findConstToRemove(const VarDecl *VD, const MatchFinder::MatchResult &Result) {
@@ -70,7 +70,7 @@ RedundantConstCheck::RedundantConstCheck(StringRef Name,
void RedundantConstCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- varDecl(isConstexpr(), unless(anyOf(hasAncestor(varTemplateDecl()),
+ varDecl(isConstexpr(), unless(anyOf(hasAncestor(VarTemplateDecl()),
hasType(referenceType()))))
.bind("var_decl"),
this);
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 3312beebcff55..96b962eec54c6 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -157,17 +157,17 @@ New checks
Suggests insertion of ``std::move(...)`` to turn copy assignment operator
calls into move assignment ones, when deemed valid and profitable.
+- New :doc:`readability-redundant-const
+ <clang-tidy/checks/readability/redundant-const>` check.
+
+ Detects redundant ``const`` specifiers on variable declarations.
+
- New :doc:`readability-redundant-qualified-alias
<clang-tidy/checks/readability/redundant-qualified-alias>` check.
Finds redundant identity type aliases that re-expose a qualified name and can
be replaced with a ``using`` declaration.
-- New :doc:`readability-redundant-const
- <clang-tidy/checks/readability/redundant-const>` check.
-
- Detects redundant ``const`` specifiers on variable declarations.
-
- New :doc:`readability-trailing-comma
<clang-tidy/checks/readability/trailing-comma>` check.
>From 0f544a905ed0b861d9efb9d2f5a271ff1b5decef Mon Sep 17 00:00:00 2001
From: Berkay Sahin <berkaysahindev at gmail.com>
Date: Wed, 1 Apr 2026 20:07:16 +0300
Subject: [PATCH 3/6] Update
clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
Co-authored-by: EugeneZelenko <eugene.zelenko at gmail.com>
---
.../docs/clang-tidy/checks/readability/redundant-const.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
index ed6957f21e312..c33c0f5cd155b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
@@ -1,7 +1,7 @@
.. title:: clang-tidy - readability-redundant-const
readability-redundant-const
-=============================
+===========================
Detects redundant ``const`` specifiers on variable declarations.
>From 5030149d16eac48351d41400d4a2cf863404a13e Mon Sep 17 00:00:00 2001
From: Berkay Sahin <berkaysahindev at gmail.com>
Date: Fri, 3 Apr 2026 23:09:08 +0300
Subject: [PATCH 4/6] Update
clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
Co-authored-by: Victor Chernyakin <chernyakin.victor.j at outlook.com>
---
.../test/clang-tidy/checkers/readability/redundant-const.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
index 6a49e9837b414..6a749b8f02161 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-const %t --
+// RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-const %t
struct Foo {};
>From b69400b2d6e69c6f7e36b447f84bc950ab3f27e1 Mon Sep 17 00:00:00 2001
From: Berkay Sahin <berkaysahindev at gmail.com>
Date: Fri, 3 Apr 2026 23:10:18 +0300
Subject: [PATCH 5/6] Update docs to avoid confusion
Co-authored-by: Victor Chernyakin <chernyakin.victor.j at outlook.com>
---
.../docs/clang-tidy/checks/readability/redundant-const.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
index c33c0f5cd155b..a8c265488d057 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst
@@ -10,9 +10,9 @@ Examples:
.. code-block:: c++
// Finds:
- constexpr const int var = {}; // redundant use of `const`
+ constexpr const int var = 10; // redundant use of `const`
// replaced by:
- constexpr int var = {};
+ constexpr int var = 10;
// Finds:
constexpr const int arr[] = {}; // redundant use of `const`
>From 72c618b0868d34b96033296343568434ee0f2bf5 Mon Sep 17 00:00:00 2001
From: Berkay Sahin <berkaysahindev at gmail.com>
Date: Fri, 3 Apr 2026 23:26:05 +0300
Subject: [PATCH 6/6] Simplifies const search logic
Co-authored-by: Victor Chernyakin <chernyakin.victor.j at outlook.com>
---
.../readability/RedundantConstCheck.cpp | 28 +++++++------------
1 file changed, 10 insertions(+), 18 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
index 421143db7b2b7..f7cc78cf7f19f 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp
@@ -31,26 +31,18 @@ findConstToRemove(const VarDecl *VD, const MatchFinder::MatchResult &Result) {
VD->getType()->isNullPtrType() ||
VD->getType()->isMemberPointerType();
- const auto ConstSearchStartLoc = [&]() -> std::optional<SourceLocation> {
- if (!IsPointer)
- return VD->getBeginLoc();
-
- SourceLocation StarLoc = utils::lexer::findPreviousTokenKind(
+ // If the 'findPreviousTokenKind' below fails,
+ // we know it is a pointer but cannot find the start token.
+ // This can happen when either type is aliased or `auto` was used.
+ // e.g: constexpr const auto const str = "hello";
+ // In cases like this, clang analyzer already warns about the use of const
+ // as duplicate, so we can safely ignore these cases.
+ const SourceLocation ConstSearchStartLoc = !IsPointer
+ ? VD->getBeginLoc()
+ : utils::lexer::findPreviousTokenKind(
NameBeginLoc, SM, Result.Context->getLangOpts(), tok::star);
- if (StarLoc.isValid())
- return StarLoc;
-
- // We know it is a pointer but cannot find the start token.
- // This can happen when either type is aliased or `auto` was used.
- // e.g: constexpr const auto const str = "hello";
- // In cases like this, clang analyzer already warns about the use of const
- // as duplicate, so we can safely ignore these cases.
-
- return std::nullopt;
- }();
-
- if (!ConstSearchStartLoc || !ConstSearchStartLoc->isValid())
+ if (ConstSearchStartLoc.isInvalid())
return std::nullopt;
const CharSourceRange FileRange = Lexer::makeFileCharRange(
More information about the cfe-commits
mailing list