]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix memchr path in std::ranges::find for non-common range [PR115799]
authorJonathan Wakely <jwakely@redhat.com>
Fri, 5 Jul 2024 17:58:00 +0000 (18:58 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Sun, 7 Jul 2024 11:26:08 +0000 (12:26 +0100)
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.

libstdc++-v3/include/bits/ranges_util.h
libstdc++-v3/testsuite/25_algorithms/find/constrained.cc

index 186acae4f70b7d751b2eb6315ff60012e908e9ad..a1f42875b11d9470e5ae91280c5742be449972d1 100644 (file)
@@ -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;
                  }
 
index e94751fcf89c747740cef41719ac0f0ceeb3eb0a..7357a40bcc43792ef76fbd2fc7fa8a9e155c7aa4 100644 (file)
@@ -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();
 }