https://github.com/kuhar updated https://github.com/llvm/llvm-project/pull/177457
>From 9f2582dee9857f653fcefd3745e2589b079872d8 Mon Sep 17 00:00:00 2001 From: Jakub Kuderski <[email protected]> Date: Thu, 22 Jan 2026 15:28:32 -0500 Subject: [PATCH 1/4] [clang-tidy] Add replace_ to llvm-use-ranges --- .../clang-tidy/llvm/UseRangesCheck.cpp | 51 ++++++++++++------- .../clang-tidy/checkers/llvm/use-ranges.cpp | 24 +++++++-- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp index 0d09210c86df5..06c73feba9dd1 100644 --- a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp @@ -50,28 +50,43 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { const auto AddStdToLLVM = [&Results](llvm::IntrusiveRefCntPtr<Replacer> Replacer, std::initializer_list<StringRef> Names) { - for (const auto &Name : Names) + for (StringRef Name : Names) Results.try_emplace(("::std::" + Name).str(), Replacer); }; - // Single range algorithms + // Single range algorithms. AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(SingleSig), - {"all_of", "any_of", - "none_of", "for_each", - "find", "find_if", - "find_if_not", "fill", - "count", "count_if", - "copy", "copy_if", - "transform", "replace", - "remove_if", "stable_sort", - "partition", "partition_point", - "is_sorted", "min_element", - "max_element", "binary_search", - "lower_bound", "upper_bound", - "unique", "uninitialized_copy", - "adjacent_find"}); - - // Two range algorithms + {"adjacent_find", + "all_of", + "any_of", + "binary_search", + "copy", + "copy_if", + "count", + "count_if", + "fill", + "find", + "find_if", + "find_if_not", + "for_each", + "is_sorted", + "lower_bound", + "max_element", + "min_element", + "none_of", + "partition", + "partition_point", + "remove_if", + "replace", + "replace_copy", + "replace_copy_if", + "stable_sort", + "transform", + "uninitialized_copy", + "unique", + "upper_bound"}); + + // Two range algorithms. AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(TwoSig), {"equal", "mismatch", "includes", "search"}); diff --git a/clang-tools-extra/test/clang-tidy/checkers/llvm/use-ranges.cpp b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-ranges.cpp index 9a52cdae2c2bc..58cdeb440eaa3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/llvm/use-ranges.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-ranges.cpp @@ -66,6 +66,14 @@ bool is_sorted(ForwardIt first, ForwardIt last); template <class InputIt1, class InputIt2> bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); +template <class InputIt, class OutputIt, class T> +OutputIt replace_copy(InputIt first, InputIt last, OutputIt d_first, + const T& old_value, const T& new_value); + +template <class InputIt, class OutputIt, class UnaryPredicate, class T> +OutputIt replace_copy_if(InputIt first, InputIt last, OutputIt d_first, + UnaryPredicate p, const T& new_value); + } // namespace std bool is_even(int x); @@ -74,7 +82,7 @@ void double_ref(int& x); void test_positive() { std::vector<int> vec; int arr[5] = {1, 2, 3, 4, 5}; - + auto it1 = std::find(vec.begin(), vec.end(), 3); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use an LLVM range-based algorithm // CHECK-FIXES: auto it1 = llvm::find(vec, 3); @@ -111,7 +119,7 @@ void test_positive() { std::fill(vec.begin(), vec.end(), 0); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use an LLVM range-based algorithm // CHECK-FIXES: llvm::fill(vec, 0); - + auto last = std::unique(vec.begin(), vec.end()); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use an LLVM range-based algorithm // CHECK-FIXES: auto last = llvm::unique(vec); @@ -123,18 +131,26 @@ void test_positive() { std::includes(vec.begin(), vec.end(), std::begin(arr), std::end(arr)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use an LLVM range-based algorithm // CHECK-FIXES: llvm::includes(vec, arr); + + std::replace_copy(vec.begin(), vec.end(), vec2.begin(), 1, 2); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use an LLVM range-based algorithm + // CHECK-FIXES: llvm::replace_copy(vec, vec2.begin(), 1, 2); + + std::replace_copy_if(vec.begin(), vec.end(), vec2.begin(), is_even, 0); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use an LLVM range-based algorithm + // CHECK-FIXES: llvm::replace_copy_if(vec, vec2.begin(), is_even, 0); } void test_negative() { std::vector<int> v; - + // can not use `llvm::sort` because of potential different ordering from `std::sort`. std::sort(v.begin(), v.end()); //non-begin/end iterators auto it1 = std::find(v.begin() + 1, v.end(), 2); auto it2 = std::find(v.begin(), v.end() - 1, 2); - + // Using different containers (3-arg equal) std::vector<int> v2; bool eq = std::equal(v.begin(), v.end(), v2.begin()); >From 2402b7ce5cfb40df38798f2aea767390ddc137c6 Mon Sep 17 00:00:00 2001 From: Jakub Kuderski <[email protected]> Date: Thu, 22 Jan 2026 19:31:20 -0500 Subject: [PATCH 2/4] Add const --- clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp index 06c73feba9dd1..70d8e75405e91 100644 --- a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp @@ -50,7 +50,7 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { const auto AddStdToLLVM = [&Results](llvm::IntrusiveRefCntPtr<Replacer> Replacer, std::initializer_list<StringRef> Names) { - for (StringRef Name : Names) + for (const StringRef Name : Names) Results.try_emplace(("::std::" + Name).str(), Replacer); }; >From 9b5b284266cfcd9fad793c8f099101c7baf0ae45 Mon Sep 17 00:00:00 2001 From: Jakub Kuderski <[email protected]> Date: Thu, 22 Jan 2026 19:38:37 -0500 Subject: [PATCH 3/4] Update docs --- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++ .../docs/clang-tidy/checks/llvm/use-ranges.rst | 14 +++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 5af634c77f54d..e8e08080b8525 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -137,6 +137,10 @@ Changes in existing checks now uses separate note diagnostics for each uninitialized enumerator, making it easier to see which specific enumerators need explicit initialization. +- Improved :doc:`llvm-use-ranges + <clang-tidy/checks/llvm/use-ranges>` check by adding support for the following + algorithms: ``std::replace_copy`` and ``std::replace_copy_if``. + Removed checks ^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst b/clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst index 1a0454703822e..6ef7f476ba2ff 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst @@ -27,18 +27,19 @@ Supported algorithms Calls to the following STL algorithms are checked: +``std::adjacent_find``, ``std::all_of``, ``std::any_of``, ``std::binary_search``, -``std::copy``, ``std::copy_if``, -``std::count``, +``std::copy``, ``std::count_if``, +``std::count``, ``std::equal``, ``std::fill``, -``std::find``, -``std::find_if``, ``std::find_if_not``, +``std::find_if``, +``std::find``, ``std::for_each``, ``std::includes``, ``std::is_sorted``, @@ -47,10 +48,13 @@ Calls to the following STL algorithms are checked: ``std::min_element``, ``std::mismatch``, ``std::none_of``, -``std::partition``, ``std::partition_point``, +``std::partition``, ``std::remove_if``, +``std::replace_copy_if``, +``std::replace_copy``, ``std::replace``, +``std::search``, ``std::stable_sort``, ``std::transform``, ``std::uninitialized_copy``, >From 120ecb4905293110b45d30c3e3ff02fb1e07794a Mon Sep 17 00:00:00 2001 From: Jakub Kuderski <[email protected]> Date: Thu, 22 Jan 2026 19:59:09 -0500 Subject: [PATCH 4/4] Reorder --- clang-tools-extra/docs/ReleaseNotes.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index e8e08080b8525..099a9fa9c2a19 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -114,6 +114,10 @@ Changes in existing checks ``std::get_temporary_buffer`` to the default list of unsafe functions. (This function is unsafe, useless, deprecated in C++17 and removed in C++20). +- Improved :doc:`llvm-use-ranges + <clang-tidy/checks/llvm/use-ranges>` check by adding support for the following + algorithms: ``std::replace_copy`` and ``std::replace_copy_if``. + - Improved :doc:`misc-const-correctness <clang-tidy/checks/misc/const-correctness>` check: @@ -137,10 +141,6 @@ Changes in existing checks now uses separate note diagnostics for each uninitialized enumerator, making it easier to see which specific enumerators need explicit initialization. -- Improved :doc:`llvm-use-ranges - <clang-tidy/checks/llvm/use-ranges>` check by adding support for the following - algorithms: ``std::replace_copy`` and ``std::replace_copy_if``. - Removed checks ^^^^^^^^^^^^^^ _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
