diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-07-08 10:45:52 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-07-10 22:05:21 +0100 |
commit | cda469a59e222496248025e0834a15d466f79d4a (patch) | |
tree | 99339a19ce69f9681522c7d6a424da80add2480c | |
parent | aae535f3a870659d1f002f82bd585de0bcec7905 (diff) | |
download | gcc-cda469a59e222496248025e0834a15d466f79d4a.zip gcc-cda469a59e222496248025e0834a15d466f79d4a.tar.gz gcc-cda469a59e222496248025e0834a15d466f79d4a.tar.bz2 |
libstdc++: ranges::find needs explicit conversion to size_t [PR115799]
For an integer-class type we need to use an explicit conversion to size_t.
libstdc++-v3/ChangeLog:
PR libstdc++/115799
* include/bits/ranges_util.h (__find_fn): Make conversion
from difference type ti size_t explicit.
* testsuite/25_algorithms/find/bytes.cc: Check ranges::find with
__gnu_test::test_contiguous_range.
* testsuite/std/ranges/range.cc: Adjust expected difference_type
for __gnu_test::test_contiguous_range.
* testsuite/util/testsuite_iterators.h (contiguous_iterator_wrapper):
Use __max_diff_type as difference type.
(test_range::sentinel, test_sized_range_sized_sent::sentinel):
Ensure that operator- returns difference_type.
-rw-r--r-- | libstdc++-v3/include/bits/ranges_util.h | 3 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/25_algorithms/find/bytes.cc | 10 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/ranges/range.cc | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/util/testsuite_iterators.h | 42 |
4 files changed, 48 insertions, 12 deletions
diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index a1f4287..e6d9607 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -506,9 +506,10 @@ namespace ranges if (static_cast<_Vt>(__value) == __value) [[likely]] if (__n > 0) { + const size_t __nu = static_cast<size_t>(__n); const int __ival = static_cast<int>(__value); const void* __p0 = std::to_address(__first); - if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) + if (auto __p1 = __builtin_memchr(__p0, __ival, __nu)) __n = (const char*)__p1 - (const char*)__p0; } return __first + __n; diff --git a/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc b/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc index e1d6c01..03dada0 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/bytes.cc @@ -114,9 +114,19 @@ test_non_characters() #endif } +#if __cpp_lib_ranges +void +test_pr115799c0(__gnu_test::test_contiguous_range<char> r) +{ + // Non-common range with integer-class type as difference_type. + (void) std::ranges::find(r, 'a'); +} +#endif + void test_pr115799c2(__gnu_test::input_iterator_wrapper<char> i) { + // Non-contiguous range of character type. (void) std::find(i, i, 'a'); } diff --git a/libstdc++-v3/testsuite/std/ranges/range.cc b/libstdc++-v3/testsuite/std/ranges/range.cc index 760f6ff..5464a9b 100644 --- a/libstdc++-v3/testsuite/std/ranges/range.cc +++ b/libstdc++-v3/testsuite/std/ranges/range.cc @@ -56,6 +56,7 @@ static_assert( std::ranges::range<test_output_sized_range<int>&> ); using std::same_as; using C = test_contiguous_range<char>; +using R = test_random_access_range<char>; using I = test_input_range<char>; using O = test_output_range<char>; @@ -69,7 +70,9 @@ static_assert( same_as<std::ranges::sentinel_t<C>, static_assert( same_as<std::ranges::sentinel_t<O>, decltype(std::declval<O&>().end())> ); -static_assert( same_as<std::ranges::range_difference_t<C>, +static_assert( ! same_as<std::ranges::range_difference_t<C>, + std::ptrdiff_t> ); // __detail::__max_diff_type +static_assert( same_as<std::ranges::range_difference_t<R>, std::ptrdiff_t> ); static_assert( same_as<std::ranges::range_difference_t<O>, std::ptrdiff_t> ); diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h index ec29712..e7f7abe 100644 --- a/libstdc++-v3/testsuite/util/testsuite_iterators.h +++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h @@ -34,6 +34,10 @@ #include <bits/move.h> #endif +#if __cplusplus > 201703L +#include <bits/max_size_type.h> +#endif + #ifndef _TESTSUITE_ITERATORS #define _TESTSUITE_ITERATORS @@ -675,6 +679,9 @@ namespace __gnu_test using iterator_concept = std::contiguous_iterator_tag; + // Use an integer-class type to try and break the library code. + using difference_type = std::ranges::__detail::__max_diff_type; + contiguous_iterator_wrapper& operator++() { @@ -706,27 +713,42 @@ namespace __gnu_test } contiguous_iterator_wrapper& - operator+=(std::ptrdiff_t n) + operator+=(difference_type n) { - random_access_iterator_wrapper<T>::operator+=(n); + auto d = static_cast<std::ptrdiff_t>(n); + random_access_iterator_wrapper<T>::operator+=(d); return *this; } friend contiguous_iterator_wrapper - operator+(contiguous_iterator_wrapper iter, std::ptrdiff_t n) + operator+(contiguous_iterator_wrapper iter, difference_type n) { return iter += n; } friend contiguous_iterator_wrapper - operator+(std::ptrdiff_t n, contiguous_iterator_wrapper iter) + operator+(difference_type n, contiguous_iterator_wrapper iter) { return iter += n; } contiguous_iterator_wrapper& - operator-=(std::ptrdiff_t n) + operator-=(difference_type n) { return *this += -n; } friend contiguous_iterator_wrapper - operator-(contiguous_iterator_wrapper iter, std::ptrdiff_t n) + operator-(contiguous_iterator_wrapper iter, difference_type n) { return iter -= n; } + + friend difference_type + operator-(contiguous_iterator_wrapper l, contiguous_iterator_wrapper r) + { + const random_access_iterator_wrapper<T>& lbase = l; + const random_access_iterator_wrapper<T>& rbase = r; + return static_cast<difference_type>(lbase - rbase); + } + + decltype(auto) operator[](difference_type n) const + { + auto d = static_cast<std::ptrdiff_t>(n); + return random_access_iterator_wrapper<T>::operator[](d); + } }; template<typename T> @@ -788,11 +810,11 @@ namespace __gnu_test friend auto operator-(const sentinel& s, const I& i) noexcept requires std::random_access_iterator<I> - { return s.end - i.ptr; } + { return std::iter_difference_t<I>(s.end - i.ptr); } friend auto operator-(const I& i, const sentinel& s) noexcept requires std::random_access_iterator<I> - { return i.ptr - s.end; } + { return std::iter_difference_t<I>(i.ptr - s.end); } }; protected: @@ -890,11 +912,11 @@ namespace __gnu_test friend std::iter_difference_t<I> operator-(const sentinel& s, const I& i) noexcept - { return s.end - i.ptr; } + { return std::iter_difference_t<I>(s.end - i.ptr); } friend std::iter_difference_t<I> operator-(const I& i, const sentinel& s) noexcept - { return i.ptr - s.end; } + { return std::iter_difference_t<I>(i.ptr - s.end); } }; auto end() & |