https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/152047
>From bb17fb65d031190efff6a6ec1c0ca6d9c0d35abb Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Tue, 5 Aug 2025 01:15:02 +0300 Subject: [PATCH 1/3] [clang-tidy] Add new check 'llvm-use-ranges' --- .../clang-tidy/llvm/CMakeLists.txt | 1 + .../clang-tidy/llvm/LLVMTidyModule.cpp | 2 + .../clang-tidy/llvm/UseRangesCheck.cpp | 90 ++++++++++++ .../clang-tidy/llvm/UseRangesCheck.h | 33 +++++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 3 +- .../clang-tidy/checks/llvm/use-ranges.rst | 58 ++++++++ .../clang-tidy/checkers/llvm/use-ranges.cpp | 128 ++++++++++++++++++ 8 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/llvm/UseRangesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/llvm/use-ranges.cpp diff --git a/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt b/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt index 41386cdb55b1f..78ef0444305ff 100644 --- a/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt @@ -12,6 +12,7 @@ add_clang_library(clangTidyLLVMModule STATIC PreferStaticOverAnonymousNamespaceCheck.cpp TwineLocalCheck.cpp UseNewMLIROpBuilderCheck.cpp + UseRangesCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp b/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp index c7c61fd1649cc..c1f78caf44d16 100644 --- a/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp @@ -19,6 +19,7 @@ #include "PreferStaticOverAnonymousNamespaceCheck.h" #include "TwineLocalCheck.h" #include "UseNewMLIROpBuilderCheck.h" +#include "UseRangesCheck.h" namespace clang::tidy { namespace llvm_check { @@ -43,6 +44,7 @@ class LLVMModule : public ClangTidyModule { CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local"); CheckFactories.registerCheck<UseNewMlirOpBuilderCheck>( "llvm-use-new-mlir-op-builder"); + CheckFactories.registerCheck<UseRangesCheck>("llvm-use-ranges"); } ClangTidyOptions getModuleOptions() override { diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp new file mode 100644 index 0000000000000..0e11a017c60d5 --- /dev/null +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp @@ -0,0 +1,90 @@ +//===--- UseRangesCheck.cpp - clang-tidy ----------------------------------===// +// +// 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 "UseRangesCheck.h" + +namespace clang::tidy::llvm_check { + +namespace { + +class StdToLLVMReplacer : public utils::UseRangesCheck::Replacer { +public: + explicit StdToLLVMReplacer( + ArrayRef<utils::UseRangesCheck::Signature> Signatures) + : Signatures(Signatures) {} + + ArrayRef<utils::UseRangesCheck::Signature> + getReplacementSignatures() const override { + return Signatures; + } + + std::optional<std::string> + getReplaceName(const NamedDecl &OriginalName) const override { + return ("llvm::" + OriginalName.getName()).str(); + } + + std::optional<std::string> + getHeaderInclusion(const NamedDecl &) const override { + return "llvm/ADT/STLExtras.h"; + } + +private: + SmallVector<utils::UseRangesCheck::Signature> Signatures; +}; + +} // namespace + +utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { + ReplacerMap Results; + + static const Signature SingleSig = {{0}}; + static const Signature TwoSig = {{0}, {2}}; + + const auto AddStdToLLVM = + [&Results](llvm::IntrusiveRefCntPtr<Replacer> Replacer, + std::initializer_list<StringRef> Names) { + for (const auto &Name : Names) { + Results.try_emplace(("::std::" + Name).str(), Replacer); + } + }; + + // Single range algorithms + AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(SingleSig), + {"all_of", "any_of", "none_of", "for_each", + "find", "find_if", "find_if_not", "count", + "count_if", "transform", "replace", "remove_if", + "sort", "partition", "is_sorted", "min_element", + "max_element", "binary_search", "lower_bound", "upper_bound", + "unique", "copy", "copy_if", "fill"}); + + // Two range algorithms + AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(TwoSig), + {"equal", "mismatch"}); + + return Results; +} + +UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context) + : utils::UseRangesCheck(Name, Context) {} + +DiagnosticBuilder UseRangesCheck::createDiag(const CallExpr &Call) { + return diag(Call.getBeginLoc(), "use a llvm range-based algorithm"); +} + +ArrayRef<std::pair<StringRef, StringRef>> +UseRangesCheck::getFreeBeginEndMethods() const { + static const std::pair<StringRef, StringRef> Refs[] = { + {"::std::begin", "::std::end"}, + {"::std::cbegin", "::std::cend"}, + {"::std::rbegin", "::std::rend"}, + {"::std::crbegin", "::std::crend"}, + }; + return Refs; +} + +} // namespace clang::tidy::llvm_check diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.h b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.h new file mode 100644 index 0000000000000..e9904e11ced36 --- /dev/null +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.h @@ -0,0 +1,33 @@ +//===--- UseRangesCheck.h - clang-tidy --------------------------*- C++ -*-===// +// +// 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_LLVM_USERANGESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_USERANGESCHECK_H + +#include "../utils/UseRangesCheck.h" + +namespace clang::tidy::llvm_check { + +/// Finds calls to STL iterator algorithms that can be replaced with LLVM +/// range-based algorithms from `llvm/ADT/STLExtras.h`. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/llvm/use-ranges.html +class UseRangesCheck : public utils::UseRangesCheck { +public: + UseRangesCheck(StringRef Name, ClangTidyContext *Context); + + ReplacerMap getReplacerMap() const override; + DiagnosticBuilder createDiag(const CallExpr &Call) override; + ArrayRef<std::pair<StringRef, StringRef>> + getFreeBeginEndMethods() const override; +}; + +} // namespace clang::tidy::llvm_check + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_USERANGESCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 383286eb0c5a3..282d16fb9ad27 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -137,6 +137,12 @@ New checks Checks for uses of MLIR's old/to be deprecated ``OpBuilder::create<T>`` form and suggests using ``T::create`` instead. +- New :doc:`llvm-use-ranges + <clang-tidy/checks/llvm/use-ranges>` check. + + Detects calls to standard library iterator algorithms that could be replaced + with LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``. + - New :doc:`misc-override-with-different-visibility <clang-tidy/checks/misc/override-with-different-visibility>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index b0961265345c0..81285b657d850 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -248,12 +248,13 @@ Clang-Tidy Checks :doc:`linuxkernel-must-check-errs <linuxkernel/must-check-errs>`, :doc:`llvm-header-guard <llvm/header-guard>`, :doc:`llvm-include-order <llvm/include-order>`, "Yes" - :doc:`llvm-use-new-mlir-op-builder <llvm/use-new-mlir-op-builder>`, "Yes" :doc:`llvm-namespace-comment <llvm/namespace-comment>`, :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals <llvm/prefer-isa-or-dyn-cast-in-conditionals>`, "Yes" :doc:`llvm-prefer-register-over-unsigned <llvm/prefer-register-over-unsigned>`, "Yes" :doc:`llvm-prefer-static-over-anonymous-namespace <llvm/prefer-static-over-anonymous-namespace>`, :doc:`llvm-twine-local <llvm/twine-local>`, "Yes" + :doc:`llvm-use-new-mlir-op-builder <llvm/use-new-mlir-op-builder>`, "Yes" + :doc:`llvm-use-ranges <llvm/use-ranges>`, "Yes" :doc:`llvmlibc-callee-namespace <llvmlibc/callee-namespace>`, :doc:`llvmlibc-implementation-in-namespace <llvmlibc/implementation-in-namespace>`, :doc:`llvmlibc-inline-function-decl <llvmlibc/inline-function-decl>`, "Yes" 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 new file mode 100644 index 0000000000000..a5fc83ad5d2c2 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst @@ -0,0 +1,58 @@ +.. title:: clang-tidy - llvm-use-ranges + +llvm-use-ranges +=============== + +Detects calls to standard library iterator algorithms that could be replaced +with LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``. + +Example +------- + +.. code-block:: c++ + + auto it = std::find(vec.begin(), vec.end(), value); + bool all = std::all_of(vec.begin(), vec.end(), + [](int x) { return x > 0; }); + +Transforms to: + +.. code-block:: c++ + + auto it = llvm::find(vec, value); + bool all = llvm::all_of(vec, [](int x) { return x > 0; }); + +Supported algorithms +-------------------- + +Calls to the following ``std`` library algorithms are checked: + +``std::all_of``, +``std::any_of``, +``std::binary_search``, +``std::copy``, +``std::copy_if``, +``std::count``, +``std::count_if``, +``std::equal``, +``std::fill``, +``std::find``, +``std::find_if``, +``std::find_if_not``, +``std::for_each``, +``std::is_sorted``, +``std::lower_bound``, +``std::max_element``, +``std::min_element``, +``std::mismatch``, +``std::none_of``, +``std::partition``, +``std::remove_if``, +``std::replace``, +``std::sort``, +``std::transform``, +``std::unique``, +``std::upper_bound``. + +The check will add the necessary ``#include "llvm/ADT/STLExtras.h"`` directive +when applying fixes. 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 new file mode 100644 index 0000000000000..3c42caa8cc1d1 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/llvm/use-ranges.cpp @@ -0,0 +1,128 @@ +// RUN: %check_clang_tidy %s llvm-use-ranges %t + +// Test that the header is included +// CHECK-FIXES: #include "llvm/ADT/STLExtras.h" + +namespace std { + +template <typename T> class vector { +public: + using iterator = T *; + using const_iterator = const T *; + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; +}; + +template <typename T> T* begin(T (&arr)[5]); +template <typename T> T* end(T (&arr)[5]); + +template <class InputIt, class T> +InputIt find(InputIt first, InputIt last, const T &value); + +template <class RandomIt> +void sort(RandomIt first, RandomIt last); + +template <class InputIt, class UnaryPredicate> +bool all_of(InputIt first, InputIt last, UnaryPredicate p); + +template <class InputIt, class UnaryFunction> +UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f); + +template <class ForwardIt, class T> +ForwardIt remove(ForwardIt first, ForwardIt last, const T& value); + +template <class ForwardIt> +ForwardIt min_element(ForwardIt first, ForwardIt last); + +template <class InputIt1, class InputIt2> +bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); + +template <class InputIt1, class InputIt2> +bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2); + +template <class InputIt, class OutputIt> +OutputIt copy(InputIt first, InputIt last, OutputIt d_first); + +template <class ForwardIt, class T> +void fill(ForwardIt first, ForwardIt last, const T& value); + +template <class BidirIt> +void reverse(BidirIt first, BidirIt last); + +template <class ForwardIt> +ForwardIt unique(ForwardIt first, ForwardIt last); + +template <class ForwardIt> +bool is_sorted(ForwardIt first, ForwardIt last); + +} // namespace std + +bool is_even(int x); +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 a llvm range-based algorithm + // CHECK-FIXES: auto it1 = llvm::find(vec, 3); + + auto it2 = std::find(std::begin(arr), std::end(arr), 3); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a llvm range-based algorithm + // CHECK-FIXES: auto it2 = llvm::find(arr, 3); + + std::sort(vec.begin(), vec.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm + // CHECK-FIXES: llvm::sort(vec); + + bool all = std::all_of(vec.begin(), vec.end(), is_even); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a llvm range-based algorithm + // CHECK-FIXES: bool all = llvm::all_of(vec, is_even); + + std::for_each(vec.begin(), vec.end(), double_ref); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm + // CHECK-FIXES: llvm::for_each(vec, double_ref); + + auto min_it = std::min_element(vec.begin(), vec.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a llvm range-based algorithm + // CHECK-FIXES: auto min_it = llvm::min_element(vec); + + std::vector<int> vec2; + bool eq = std::equal(vec.begin(), vec.end(), vec2.begin(), vec2.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a llvm range-based algorithm + // CHECK-FIXES: bool eq = llvm::equal(vec, vec2); + + std::copy(vec.begin(), vec.end(), vec2.begin()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm + // CHECK-FIXES: llvm::copy(vec, vec2.begin()); + + std::fill(vec.begin(), vec.end(), 0); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a 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 a llvm range-based algorithm + // CHECK-FIXES: auto last = llvm::unique(vec); + + bool sorted = std::is_sorted(vec.begin(), vec.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a llvm range-based algorithm + // CHECK-FIXES: bool sorted = llvm::is_sorted(vec); +} + +void test_negative() { + std::vector<int> v; + + //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 fc2a81b0e9b5c507650d8fb5bd3a5bb0c8b8429b Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Tue, 5 Aug 2025 10:38:30 +0300 Subject: [PATCH 2/3] adjust supported algorithms and convert `llvm` -> `LLVM` --- .../clang-tidy/llvm/UseRangesCheck.cpp | 19 +++++---- .../clang-tidy/checks/llvm/use-ranges.rst | 4 +- .../clang-tidy/checkers/llvm/use-ranges.cpp | 39 ++++++++++++------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp index 0e11a017c60d5..4c9eb923c4dd1 100644 --- a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp @@ -55,16 +55,19 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { // Single range algorithms AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(SingleSig), - {"all_of", "any_of", "none_of", "for_each", - "find", "find_if", "find_if_not", "count", - "count_if", "transform", "replace", "remove_if", - "sort", "partition", "is_sorted", "min_element", - "max_element", "binary_search", "lower_bound", "upper_bound", - "unique", "copy", "copy_if", "fill"}); + {"all_of", "any_of", "none_of", + "for_each", "find", "find_if", + "find_if_not", "count", "count_if", + "transform", "replace", "remove_if", + "stable_sort", "partition", "partition_point", + "is_sorted", "min_element", "max_element", + "binary_search", "lower_bound", "upper_bound", + "unique", "copy", "copy_if", + "fill"}); // Two range algorithms AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(TwoSig), - {"equal", "mismatch"}); + {"equal", "mismatch", "includes"}); return Results; } @@ -73,7 +76,7 @@ UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context) : utils::UseRangesCheck(Name, Context) {} DiagnosticBuilder UseRangesCheck::createDiag(const CallExpr &Call) { - return diag(Call.getBeginLoc(), "use a llvm range-based algorithm"); + return diag(Call.getBeginLoc(), "use a LLVM range-based algorithm"); } ArrayRef<std::pair<StringRef, StringRef>> 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 a5fc83ad5d2c2..34352ffcb9481 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 @@ -40,6 +40,7 @@ Calls to the following ``std`` library algorithms are checked: ``std::find_if``, ``std::find_if_not``, ``std::for_each``, +``std::includes``, ``std::is_sorted``, ``std::lower_bound``, ``std::max_element``, @@ -47,9 +48,10 @@ Calls to the following ``std`` library algorithms are checked: ``std::mismatch``, ``std::none_of``, ``std::partition``, +``std::partition_point``, ``std::remove_if``, ``std::replace``, -``std::sort``, +``std::stable_sort``, ``std::transform``, ``std::unique``, ``std::upper_bound``. 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 3c42caa8cc1d1..70bdf1fed8417 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 @@ -27,6 +27,9 @@ InputIt find(InputIt first, InputIt last, const T &value); template <class RandomIt> void sort(RandomIt first, RandomIt last); +template <class RandomIt> +void stable_sort(RandomIt first, RandomIt last); + template <class InputIt, class UnaryPredicate> bool all_of(InputIt first, InputIt last, UnaryPredicate p); @@ -60,6 +63,9 @@ ForwardIt unique(ForwardIt first, ForwardIt last); template <class ForwardIt> bool is_sorted(ForwardIt first, ForwardIt last); +template <class InputIt1, class InputIt2> +bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); + } // namespace std bool is_even(int x); @@ -70,54 +76,61 @@ void test_positive() { int arr[5] = {1, 2, 3, 4, 5}; auto it1 = std::find(vec.begin(), vec.end(), 3); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a LLVM range-based algorithm // CHECK-FIXES: auto it1 = llvm::find(vec, 3); auto it2 = std::find(std::begin(arr), std::end(arr), 3); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a LLVM range-based algorithm // CHECK-FIXES: auto it2 = llvm::find(arr, 3); - std::sort(vec.begin(), vec.end()); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm - // CHECK-FIXES: llvm::sort(vec); + std::stable_sort(vec.begin(), vec.end()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a LLVM range-based algorithm + // CHECK-FIXES: llvm::stable_sort(vec); bool all = std::all_of(vec.begin(), vec.end(), is_even); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use a LLVM range-based algorithm // CHECK-FIXES: bool all = llvm::all_of(vec, is_even); std::for_each(vec.begin(), vec.end(), double_ref); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a LLVM range-based algorithm // CHECK-FIXES: llvm::for_each(vec, double_ref); auto min_it = std::min_element(vec.begin(), vec.end()); - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a LLVM range-based algorithm // CHECK-FIXES: auto min_it = llvm::min_element(vec); std::vector<int> vec2; bool eq = std::equal(vec.begin(), vec.end(), vec2.begin(), vec2.end()); - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a LLVM range-based algorithm // CHECK-FIXES: bool eq = llvm::equal(vec, vec2); std::copy(vec.begin(), vec.end(), vec2.begin()); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a LLVM range-based algorithm // CHECK-FIXES: llvm::copy(vec, vec2.begin()); std::fill(vec.begin(), vec.end(), 0); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a 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 a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use a LLVM range-based algorithm // CHECK-FIXES: auto last = llvm::unique(vec); bool sorted = std::is_sorted(vec.begin(), vec.end()); - // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a llvm range-based algorithm + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use a LLVM range-based algorithm // CHECK-FIXES: bool sorted = llvm::is_sorted(vec); + + std::includes(vec.begin(), vec.end(), std::begin(arr), std::end(arr)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a LLVM range-based algorithm + // CHECK-FIXES: llvm::includes(vec, arr); } 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); >From aa37995cbcc7d882f4955fd17dcd2f305cd5e8a5 Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Sat, 23 Aug 2025 08:24:15 +0300 Subject: [PATCH 3/3] standart library -> STL library --- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++-- clang-tools-extra/docs/clang-tidy/checks/llvm/use-ranges.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 282d16fb9ad27..edeedfc8d94a2 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -140,8 +140,8 @@ New checks - New :doc:`llvm-use-ranges <clang-tidy/checks/llvm/use-ranges>` check. - Detects calls to standard library iterator algorithms that could be replaced - with LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``. + Detects calls to STL library iterator algorithms that could be replaced with + LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``. - New :doc:`misc-override-with-different-visibility <clang-tidy/checks/misc/override-with-different-visibility>` check. 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 34352ffcb9481..b9ad3e16f9b28 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 @@ -3,8 +3,8 @@ llvm-use-ranges =============== -Detects calls to standard library iterator algorithms that could be replaced -with LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``. +Detects calls to STL library iterator algorithms that could be replaced with +LLVM range-based algorithms from ``llvm/ADT/STLExtras.h``. Example ------- _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits