diff mbox series

[committed] libstdc++: Fix memchr path in std::ranges::find for non-common range [PR115799]

Message ID 20240707112955.288489-1-jwakely@redhat.com
State New
Headers show
Series [committed] libstdc++: Fix memchr path in std::ranges::find for non-common range [PR115799] | expand

Commit Message

Jonathan Wakely July 7, 2024, 11:29 a.m. UTC
Tested x86_64-linux. Pushed to trunk.

-- >8 --

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       | 19 +++++++++----------
 .../25_algorithms/find/constrained.cc         | 10 ++++++++++
 2 files changed, 19 insertions(+), 10 deletions(-)
diff mbox series

Patch

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();
 }