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 <[email protected]> Date: Tue, 31 Mar 2026 22:20:46 +0300 Subject: [PATCH 1/8] [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 <[email protected]> Date: Tue, 31 Mar 2026 22:56:39 +0300 Subject: [PATCH 2/8] [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 <[email protected]> Date: Wed, 1 Apr 2026 20:07:16 +0300 Subject: [PATCH 3/8] Update clang-tools-extra/docs/clang-tidy/checks/readability/redundant-const.rst Co-authored-by: EugeneZelenko <[email protected]> --- .../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 <[email protected]> Date: Fri, 3 Apr 2026 23:09:08 +0300 Subject: [PATCH 4/8] Update clang-tools-extra/test/clang-tidy/checkers/readability/redundant-const.cpp Co-authored-by: Victor Chernyakin <[email protected]> --- .../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 <[email protected]> Date: Fri, 3 Apr 2026 23:10:18 +0300 Subject: [PATCH 5/8] Update docs to avoid confusion Co-authored-by: Victor Chernyakin <[email protected]> --- .../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 <[email protected]> Date: Fri, 3 Apr 2026 23:26:05 +0300 Subject: [PATCH 6/8] Simplifies const search logic Co-authored-by: Victor Chernyakin <[email protected]> --- .../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( >From 3da91747a6f59db5ae8c5d8f797320f185be3e85 Mon Sep 17 00:00:00 2001 From: Berkay Sahin <[email protected]> Date: Fri, 3 Apr 2026 23:45:08 +0300 Subject: [PATCH 7/8] Fix linter issues --- .../clang-tidy/readability/RedundantConstCheck.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp index f7cc78cf7f19f..b14f4a2f6e329 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp @@ -37,10 +37,11 @@ findConstToRemove(const VarDecl *VD, const MatchFinder::MatchResult &Result) { // 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); + const SourceLocation ConstSearchStartLoc = + !IsPointer + ? VD->getBeginLoc() + : utils::lexer::findPreviousTokenKind( + NameBeginLoc, SM, Result.Context->getLangOpts(), tok::star); if (ConstSearchStartLoc.isInvalid()) return std::nullopt; >From 9855bc6ba6dd3d1db15548f6f52feb591f67c178 Mon Sep 17 00:00:00 2001 From: Berkay Sahin <[email protected]> Date: Sat, 4 Apr 2026 00:17:41 +0300 Subject: [PATCH 8/8] Fix compile --- .../clang-tidy/readability/RedundantConstCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp index b14f4a2f6e329..8449d32d191ca 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantConstCheck.cpp @@ -47,7 +47,7 @@ findConstToRemove(const VarDecl *VD, const MatchFinder::MatchResult &Result) { return std::nullopt; const CharSourceRange FileRange = Lexer::makeFileCharRange( - CharSourceRange::getCharRange(*ConstSearchStartLoc, NameBeginLoc), SM, + CharSourceRange::getCharRange(ConstSearchStartLoc, NameBeginLoc), SM, Result.Context->getLangOpts()); if (!FileRange.isValid()) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
