https://github.com/ZenginU updated https://github.com/llvm/llvm-project/pull/226739
>From 585393c47572efe2e5ebf047a4e7fd54ec8b76df Mon Sep 17 00:00:00 2001 From: ZenginU <[email protected]> Date: Sat, 26 Sep 2026 18:33:36 -0400 Subject: [PATCH 1/5] Fix: Fix when std::ranges::fix is offered on a pointer type. --- .../clang-tidy/utils/UseRangesCheck.cpp | 15 +++++++++++---- .../clang-tidy/checkers/modernize/use-ranges.cpp | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index e66e1e541e461..6529c23ee5cb6 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "UseRangesCheck.h" +#include "FixItHintUtils.h" #include "Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" @@ -268,13 +269,19 @@ void UseRangesCheck::check(const MatchFinder::MatchResult &Result) { for (const auto &[First, Second, Replace] : Sig) { auto ArgNode = ArgName + std::to_string(First); if (const auto *ArgExpr = Result.Nodes.getNodeAs<Expr>(ArgNode)) { - Diag << FixItHint::CreateReplacement( - Call->getArg(Replace == Indexes::Second ? Second : First) - ->getSourceRange(), + const Expr *RangeArg = + Call->getArg(Replace == Indexes::Second ? Second : First); + std::string ReplaceText = Lexer::getSourceText( CharSourceRange::getTokenRange(ArgExpr->getSourceRange()), Result.Context->getSourceManager(), - Result.Context->getLangOpts())); + Result.Context->getLangOpts()) + .str(); + if (ArgExpr->getType()->isPointerType() && + isa<CXXMemberCallExpr>(RangeArg->IgnoreParenImpCasts())) + ReplaceText = fixit::formatDereference(*ArgExpr, *Result.Context); + Diag << FixItHint::CreateReplacement(RangeArg->getSourceRange(), + ReplaceText); } else { assert(ReverseDescriptor && "Couldn't find forward argument"); ArgNode.push_back('R'); diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp index 1724b9311e57e..e98234191c15e 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp @@ -11,7 +11,8 @@ void Positives() { std::vector<int> I, J; std::vector<std::unique_ptr<int>> K; - + std::vector<int> PointerContainers[2]; + std::vector<int> *P = PointerContainers; // Expect to have no check messages std::find(K.begin(), K.end(), nullptr); @@ -27,6 +28,18 @@ void Positives() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::find(I, 1); + std::find(P->cbegin(), P->cend(), 2); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm + // CHECK-FIXES: std::ranges::find(*P, 2); + + std::find(P->begin(), P->end(), 3); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm + // CHECK-FIXES: std::ranges::find(*P, 3); + + std::find((P + 1)->begin(), (P + 1)->end(), 4); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm + // CHECK-FIXES: std::ranges::find(*(P + 1), 4); + std::find(std::begin(I), std::end(I), 2); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::find(I, 2); >From 3eb10646f05e06a639b73d41fc92865a004f0bd3 Mon Sep 17 00:00:00 2001 From: ZenginU <[email protected]> Date: Sat, 26 Sep 2026 23:01:15 -0400 Subject: [PATCH 2/5] Add the fix to the ReleaseNotes.md --- clang-tools-extra/docs/ReleaseNotes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md index 833638a47abc6..52b201dc11d4f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.md +++ b/clang-tools-extra/docs/ReleaseNotes.md @@ -240,6 +240,10 @@ infrastructure are described first, followed by tool-specific sections. <clang-tidy/checks/modernize/use-noexcept>` when analyzing malformed template code with an unparsed exception specification. +- Improved {doc}`modernize-use-ranges + <clang-tidy/checks/modernize/use-ranges>` check by correctly dereferencing + raw pointers to containers in fix-its. + - Extend {doc}`modernize-use-nullptr <clang-tidy/checks/modernize/use-nullptr>` to turn `decltype(nullptr)` into `std::nullptr_t` from `<cstdef>`. >From 402a1245559e873af7b24579cadf118a98f1c06a Mon Sep 17 00:00:00 2001 From: ZenginU <[email protected]> Date: Sat, 26 Sep 2026 23:14:17 -0400 Subject: [PATCH 3/5] Fix ordering. --- clang-tools-extra/docs/ReleaseNotes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md index 52b201dc11d4f..ac6f6b8fe6865 100644 --- a/clang-tools-extra/docs/ReleaseNotes.md +++ b/clang-tools-extra/docs/ReleaseNotes.md @@ -240,14 +240,14 @@ infrastructure are described first, followed by tool-specific sections. <clang-tidy/checks/modernize/use-noexcept>` when analyzing malformed template code with an unparsed exception specification. -- Improved {doc}`modernize-use-ranges - <clang-tidy/checks/modernize/use-ranges>` check by correctly dereferencing - raw pointers to containers in fix-its. - - Extend {doc}`modernize-use-nullptr <clang-tidy/checks/modernize/use-nullptr>` to turn `decltype(nullptr)` into `std::nullptr_t` from `<cstdef>`. +- Improved {doc}`modernize-use-ranges + <clang-tidy/checks/modernize/use-ranges>` check by correctly dereferencing + raw pointers to containers in fix-its. + - Improved {doc}`performance-inefficient-algorithm <clang-tidy/checks/performance/inefficient-algorithm>` check to no longer produce a fix with the container or the searched-for value missing, such as >From 8c5fca45d962876215be9e6f875b4283abf5a351 Mon Sep 17 00:00:00 2001 From: ZenginU <[email protected]> Date: Sun, 27 Sep 2026 11:33:04 -0400 Subject: [PATCH 4/5] Use tooling::fixit::getText --- clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index 6529c23ee5cb6..e1e0d2a5ac077 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" +#include "clang/Tooling/FixIt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallBitVector.h" @@ -272,11 +273,7 @@ void UseRangesCheck::check(const MatchFinder::MatchResult &Result) { const Expr *RangeArg = Call->getArg(Replace == Indexes::Second ? Second : First); std::string ReplaceText = - Lexer::getSourceText( - CharSourceRange::getTokenRange(ArgExpr->getSourceRange()), - Result.Context->getSourceManager(), - Result.Context->getLangOpts()) - .str(); + tooling::fixit::getText(*ArgExpr, *Result.Context).str(); if (ArgExpr->getType()->isPointerType() && isa<CXXMemberCallExpr>(RangeArg->IgnoreParenImpCasts())) ReplaceText = fixit::formatDereference(*ArgExpr, *Result.Context); >From 1f1f4e2aa010f40d888fa8e2bf40119cb8b36f0f Mon Sep 17 00:00:00 2001 From: ZenginU <[email protected]> Date: Sun, 27 Sep 2026 14:08:15 -0400 Subject: [PATCH 5/5] Add tests and use ternary operator for dereferencing. --- clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp | 10 ++++++---- .../test/clang-tidy/checkers/modernize/use-ranges.cpp | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index e1e0d2a5ac077..ddfa19a1eb073 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -272,11 +272,13 @@ void UseRangesCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *ArgExpr = Result.Nodes.getNodeAs<Expr>(ArgNode)) { const Expr *RangeArg = Call->getArg(Replace == Indexes::Second ? Second : First); + const bool NeedsDereference = + ArgExpr->getType()->isPointerType() && + isa<CXXMemberCallExpr>(RangeArg->IgnoreParenImpCasts()); std::string ReplaceText = - tooling::fixit::getText(*ArgExpr, *Result.Context).str(); - if (ArgExpr->getType()->isPointerType() && - isa<CXXMemberCallExpr>(RangeArg->IgnoreParenImpCasts())) - ReplaceText = fixit::formatDereference(*ArgExpr, *Result.Context); + NeedsDereference + ? fixit::formatDereference(*ArgExpr, *Result.Context) + : tooling::fixit::getText(*ArgExpr, *Result.Context).str(); Diag << FixItHint::CreateReplacement(RangeArg->getSourceRange(), ReplaceText); } else { diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp index e98234191c15e..b045b9628e7ef 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp @@ -13,6 +13,7 @@ void Positives() { std::vector<std::unique_ptr<int>> K; std::vector<int> PointerContainers[2]; std::vector<int> *P = PointerContainers; + // Expect to have no check messages std::find(K.begin(), K.end(), nullptr); @@ -36,6 +37,10 @@ void Positives() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::find(*P, 3); + std::find((P)->begin(), (P)->end(), 4); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm + // CHECK-FIXES: std::ranges::find(*P, 4); + std::find((P + 1)->begin(), (P + 1)->end(), 4); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::find(*(P + 1), 4); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
