mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 23:25:24 +02:00
libstdc++: Fix ranges::stable_sort handling of null buffer [PR123180]
The logic of the null pointer check got reversed when converting the std::stable_sort code for ranges::stable_sort. libstdc++-v3/ChangeLog: PR libstdc++/123180 * include/bits/ranges_algo.h (__stable_sort_fn::operator()): Fix sense of null check. Replace typedef with alias-declaration. * testsuite/25_algorithms/stable_sort/123180.cc: New test. Reviewed-by: Patrick Palka <ppalka@redhat.com>
This commit is contained in:
committed by
Jonathan Wakely
parent
1ed9526113
commit
630c1bfbb5
@@ -2709,7 +2709,7 @@ namespace ranges
|
||||
}
|
||||
# endif
|
||||
|
||||
typedef _Temporary_buffer<_Iter, iter_value_t<_Iter>> _TmpBuf;
|
||||
using _TmpBuf = _Temporary_buffer<_Iter, iter_value_t<_Iter>>;
|
||||
// __stable_sort_adaptive sorts the range in two halves,
|
||||
// so the buffer only needs to fit half the range at once.
|
||||
_TmpBuf __buf(__first, ptrdiff_t((__last - __first + 1) / 2));
|
||||
@@ -2718,7 +2718,7 @@ namespace ranges
|
||||
__detail::__stable_sort_adaptive(__first,
|
||||
__first + _DistanceType(__buf.size()),
|
||||
__last, __buf.begin(), __comp_proj);
|
||||
else if (__buf.begin()) [[unlikely]]
|
||||
else if (__buf.begin() == nullptr) [[unlikely]]
|
||||
__detail::__inplace_stable_sort(__first, __last, __comp_proj);
|
||||
else
|
||||
__detail::__stable_sort_adaptive_resize(__first, __last, __buf.begin(),
|
||||
|
||||
66
libstdc++-v3/testsuite/25_algorithms/stable_sort/123180.cc
Normal file
66
libstdc++-v3/testsuite/25_algorithms/stable_sort/123180.cc
Normal file
@@ -0,0 +1,66 @@
|
||||
// { dg-do run }
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
# define NOEXCEPT throw()
|
||||
# define nullptr 0
|
||||
# define THROW_BAD_ALLOC throw(std::bad_alloc)
|
||||
#else
|
||||
# define NOEXCEPT noexcept
|
||||
# define THROW_BAD_ALLOC noexcept(false)
|
||||
#endif
|
||||
|
||||
std::size_t limit = -1u;
|
||||
|
||||
void* operator new(std::size_t n, const std::nothrow_t&) NOEXCEPT
|
||||
{
|
||||
if (n > limit)
|
||||
return NULL;
|
||||
return std::malloc(n);
|
||||
}
|
||||
|
||||
void* operator new(std::size_t n) THROW_BAD_ALLOC
|
||||
{
|
||||
return std::malloc(n);
|
||||
}
|
||||
|
||||
void operator delete(void* p) NOEXCEPT { std::free(p); }
|
||||
#ifdef __cpp_sized_deallocation
|
||||
void operator delete(void* p, std::size_t) NOEXCEPT { std::free(p); }
|
||||
#endif
|
||||
|
||||
void
|
||||
test_stl_algo()
|
||||
{
|
||||
int a[] = { 4, 6, 2, 1, 7, 9, 2, 2, 2, 8 };
|
||||
limit = -1u;
|
||||
std::stable_sort(a, a+10); // gets as much memory as it needs
|
||||
limit = 2 * sizeof(int);
|
||||
std::stable_sort(a, a+10); // only gets memory for two ints
|
||||
limit = 0;
|
||||
std::stable_sort(a, a+10); // gets no memory
|
||||
}
|
||||
|
||||
void
|
||||
test_ranges_algo()
|
||||
{
|
||||
#if __cplusplus >= 202002L
|
||||
int a[] = { 4, 6, 2, 1, 7, 9, 2, 2, 2, 8 };
|
||||
limit = -1u;
|
||||
std::ranges::stable_sort(a); // gets as much memory as it needs
|
||||
limit = 2 * sizeof(int);
|
||||
std::ranges::stable_sort(a); // only gets memory for two ints
|
||||
limit = 0;
|
||||
std::ranges::stable_sort(a); // gets no memory
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_stl_algo();
|
||||
test_ranges_algo();
|
||||
}
|
||||
Reference in New Issue
Block a user