Author: Daniil Dudkin Date: 2026-05-31T14:07:33+03:00 New Revision: b48743be091be62232e3d51b7481604d224b992a
URL: https://github.com/llvm/llvm-project/commit/b48743be091be62232e3d51b7481604d224b992a DIFF: https://github.com/llvm/llvm-project/commit/b48743be091be62232e3d51b7481604d224b992a.diff LOG: [clang-tidy] `use-ranges`: preserve iterator results with `.begin()` (#196036) Preserve used iterator results for `remove`, `partition`, `stable_partition`, and `rotate`-style replacements by appending `.begin()` where the ranges algorithm returns a subrange. Fix #124794 Assisted by Codex. Added: Modified: clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp index 27fc52d95921e..e36ce3adeb15f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp @@ -37,8 +37,6 @@ static constexpr const char *SingleRangeNames[] = { "replace", "replace_if", "generate", - "remove", - "remove_if", "remove_copy", "remove_copy_if", "unique_copy", @@ -59,9 +57,7 @@ static constexpr const char *SingleRangeNames[] = { "shift_left", "shift_right", "is_partitioned", - "partition", "partition_copy", - "stable_partition", "sort", "stable_sort", "is_sorted", @@ -79,7 +75,8 @@ static constexpr const char *SingleRangeNames[] = { "destroy", }; -static constexpr const char *SingleRangeBeginResultNames[] = {"unique"}; +static constexpr const char *SingleRangeBeginResultNames[] = { + "remove", "remove_if", "stable_partition", "partition", "unique"}; static constexpr const char *TwoRangeNames[] = { "equal", @@ -97,9 +94,11 @@ static constexpr const char *TwoRangeNames[] = { "is_permutation", }; -static constexpr const char *SinglePivotRangeNames[] = {"rotate", "rotate_copy", +static constexpr const char *SinglePivotRangeNames[] = {"rotate_copy", "inplace_merge"}; +static constexpr const char *SinglePivotRangeBeginResultNames[] = {"rotate"}; + namespace { class StdReplacer : public utils::UseRangesCheck::Replacer { public: @@ -176,6 +175,7 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { {SingleRangeFunc, SingleRangeBeginResultNames, BeginResultPolicy}, {TwoRangeFunc, TwoRangeNames, DefaultPolicy}, {SinglePivotFunc, SinglePivotRangeNames, DefaultPolicy}, + {SinglePivotFunc, SinglePivotRangeBeginResultNames, BeginResultPolicy}, }; SmallString<64> Buff; for (const auto &[Signatures, Values, Policy] : AlgorithmNames) { diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index af99048c2cf5d..e40150f3603da 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -580,6 +580,10 @@ Changes in existing checks - Preserved used iterator results when replacing ``std::unique`` calls with ``std::ranges::unique``. + - Preserved used iterator results when replacing ``std::remove``, + ``std::remove_if``, ``std::partition``, ``std::stable_partition``, and + ``std::rotate`` calls with their ``std::ranges`` counterparts. + - Improved :doc:`modernize-use-std-format <clang-tidy/checks/modernize/use-std-format>` check: diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h index ca9e84c8f25dd..be5e963870fc4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h @@ -96,6 +96,22 @@ ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPred pred) { return first; } +template <class ForwardIt, class T> +ForwardIt remove(ForwardIt first, ForwardIt last, const T &value); +template <class ForwardIt, class UnaryPred> +ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPred pred) { + return first; +} + +template <class ForwardIt, class UnaryPred> +ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred pred) { + return first; +} +template <class BidirIt, class UnaryPred> +BidirIt stable_partition(BidirIt first, BidirIt last, UnaryPred pred) { + return first; +} + template <class ForwardIt> ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last); } // namespace _V1 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 d4250b99e243b..1724b9311e57e 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 @@ -61,6 +61,27 @@ void Positives() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::unique(I); + I.erase(std::remove(I.begin(), I.end(), 0), I.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use a ranges version of this algorithm + // CHECK-FIXES: I.erase(std::ranges::remove(I, 0).begin(), I.end()); + + I.erase(std::remove_if(I.begin(), I.end(), [](int N) { return N == 0; }), + I.end()); + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: use a ranges version of this algorithm + // CHECK-FIXES: I.erase(std::ranges::remove_if(I, [](int N) { return N == 0; }).begin(), + + auto PartitionPoint = + std::partition(I.begin(), I.end(), [](int N) { return N == 0; }); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a ranges version of this algorithm + // CHECK-FIXES: auto PartitionPoint = + // CHECK-FIXES-NEXT: std::ranges::partition(I, [](int N) { return N == 0; }).begin(); + + auto StablePartitionPoint = + std::stable_partition(I.begin(), I.end(), [](int N) { return N == 0; }); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use a ranges version of this algorithm + // CHECK-FIXES: auto StablePartitionPoint = + // CHECK-FIXES-NEXT: std::ranges::stable_partition(I, [](int N) { return N == 0; }).begin(); + std::includes(I.begin(), I.end(), I.begin(), I.end()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::includes(I, I); @@ -89,6 +110,10 @@ void Positives() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm // CHECK-FIXES: std::ranges::rotate(I, I.begin() + 2); + auto RotatePoint = std::rotate(I.begin(), I.begin() + 2, I.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use a ranges version of this algorithm + // CHECK-FIXES: auto RotatePoint = std::ranges::rotate(I, I.begin() + 2).begin(); + using std::find; namespace my_std = std; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
