mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-19 00:55:13 +08:00
libstdc++: Do not use memset in constexpr calls to ranges::fill_n [PR101608]
libstdc++-v3/ChangeLog: PR libstdc++/101608 * include/bits/ranges_algobase.h (__fill_n_fn): Check for constant evaluation before using memset. * testsuite/25_algorithms/fill_n/constrained.cc: Check byte-sized values as well.
This commit is contained in:
parent
6ea5fb3cc7
commit
82c3657dd7
@ -527,17 +527,25 @@ namespace ranges
|
||||
if (__n <= 0)
|
||||
return __first;
|
||||
|
||||
// TODO: Generalize this optimization to contiguous iterators.
|
||||
if constexpr (is_pointer_v<_Out>
|
||||
// Note that __is_byte already implies !is_volatile.
|
||||
&& __is_byte<remove_pointer_t<_Out>>::__value
|
||||
&& integral<_Tp>)
|
||||
{
|
||||
__builtin_memset(__first, static_cast<unsigned char>(__value), __n);
|
||||
return __first + __n;
|
||||
}
|
||||
else if constexpr (is_scalar_v<_Tp>)
|
||||
if constexpr (is_scalar_v<_Tp>)
|
||||
{
|
||||
// TODO: Generalize this optimization to contiguous iterators.
|
||||
if constexpr (is_pointer_v<_Out>
|
||||
// Note that __is_byte already implies !is_volatile.
|
||||
&& __is_byte<remove_pointer_t<_Out>>::__value
|
||||
&& integral<_Tp>)
|
||||
{
|
||||
#ifdef __cpp_lib_is_constant_evaluated
|
||||
if (!std::is_constant_evaluated())
|
||||
#endif
|
||||
{
|
||||
__builtin_memset(__first,
|
||||
static_cast<unsigned char>(__value),
|
||||
__n);
|
||||
return __first + __n;
|
||||
}
|
||||
}
|
||||
|
||||
const auto __tmp = __value;
|
||||
for (; __n > 0; --__n, (void)++__first)
|
||||
*__first = __tmp;
|
||||
|
@ -73,11 +73,12 @@ test01()
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr bool
|
||||
test02()
|
||||
{
|
||||
bool ok = true;
|
||||
int x[6] = { 1, 2, 3, 4, 5, 6 };
|
||||
T x[6] = { 1, 2, 3, 4, 5, 6 };
|
||||
const int y[6] = { 1, 2, 3, 4, 5, 6 };
|
||||
const int z[6] = { 17, 17, 17, 4, 5, 6 };
|
||||
|
||||
@ -94,5 +95,6 @@ int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
static_assert(test02());
|
||||
static_assert(test02<int>());
|
||||
static_assert(test02<unsigned char>()); // PR libstdc++/101608
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user