https://gcc.gnu.org/g:762ee55d369a3257997092ef7853cf9dd4d5cc4f
commit r15-1879-g762ee55d369a3257997092ef7853cf9dd4d5cc4f Author: Jonathan Wakely <jwak...@redhat.com> Date: Fri Jul 5 18:58:00 2024 +0100 libstdc++: Fix memchr path in std::ranges::find for non-common range [PR115799] The memchr optimization introduced in r15-1857 needs to advance the start iterator instead of returning the sentinel. libstdc++-v3/ChangeLog: PR libstdc++/115799 * include/bits/ranges_util.h (__find_fn): Return iterator instead of sentinel. * testsuite/25_algorithms/find/constrained.cc: Check non-common contiguous sized range of char. Diff: --- libstdc++-v3/include/bits/ranges_util.h | 19 +++++++++---------- .../testsuite/25_algorithms/find/constrained.cc | 10 ++++++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index 186acae4f70..a1f42875b11 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -501,17 +501,16 @@ namespace ranges if constexpr (contiguous_iterator<_Iter>) if (!is_constant_evaluated()) { - if (static_cast<iter_value_t<_Iter>>(__value) != __value) - return __last; - + using _Vt = iter_value_t<_Iter>; auto __n = __last - __first; - if (__n > 0) - { - const int __ival = static_cast<int>(__value); - const void* __p0 = std::to_address(__first); - if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) - __n = (const char*)__p1 - (const char*)__p0; - } + if (static_cast<_Vt>(__value) == __value) [[likely]] + if (__n > 0) + { + const int __ival = static_cast<int>(__value); + const void* __p0 = std::to_address(__first); + if (auto __p1 = __builtin_memchr(__p0, __ival, __n)) + __n = (const char*)__p1 - (const char*)__p0; + } return __first + __n; } diff --git a/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc index e94751fcf89..7357a40bcc4 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/constrained.cc @@ -66,9 +66,19 @@ test02() static_assert(ranges::find(y, 5, &Y::j) == y+3); } +void +test_pr115799() +{ + const char str[3] = { 'a', 'b', 'c' }; + __gnu_test::test_contiguous_sized_range<const char> r(str); + VERIFY(std::ranges::find(r, 'a') == std::ranges::begin(r)); + VERIFY(std::ranges::find(r, 'a'+255) == std::ranges::end(r)); +} + int main() { test01(); test02(); + test_pr115799(); }