aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-07-05 18:58:00 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2024-07-07 12:26:08 +0100
commit762ee55d369a3257997092ef7853cf9dd4d5cc4f (patch)
treece2b5014ad91c7aa3b4834a9ff7d9a8a9a54cc17
parente78c5d0ae48b7bf539d94b77382ecc1aac260f0c (diff)
downloadgcc-762ee55d369a3257997092ef7853cf9dd4d5cc4f.zip
gcc-762ee55d369a3257997092ef7853cf9dd4d5cc4f.tar.gz
gcc-762ee55d369a3257997092ef7853cf9dd4d5cc4f.tar.bz2
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.
-rw-r--r--libstdc++-v3/include/bits/ranges_util.h19
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find/constrained.cc10
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 186acae..a1f4287 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 e94751f..7357a40 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();
}