Skip to content

Commit 7ae6e4e

Browse files
committed
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. (cherry picked from commit 82c3657)
1 parent 88b9997 commit 7ae6e4e

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

libstdc++-v3/include/bits/ranges_algobase.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -525,17 +525,25 @@ namespace ranges
525525
if (__n <= 0)
526526
return __first;
527527

528-
// TODO: Generalize this optimization to contiguous iterators.
529-
if constexpr (is_pointer_v<_Out>
530-
// Note that __is_byte already implies !is_volatile.
531-
&& __is_byte<remove_pointer_t<_Out>>::__value
532-
&& integral<_Tp>)
533-
{
534-
__builtin_memset(__first, static_cast<unsigned char>(__value), __n);
535-
return __first + __n;
536-
}
537-
else if constexpr (is_scalar_v<_Tp>)
528+
if constexpr (is_scalar_v<_Tp>)
538529
{
530+
// TODO: Generalize this optimization to contiguous iterators.
531+
if constexpr (is_pointer_v<_Out>
532+
// Note that __is_byte already implies !is_volatile.
533+
&& __is_byte<remove_pointer_t<_Out>>::__value
534+
&& integral<_Tp>)
535+
{
536+
#ifdef __cpp_lib_is_constant_evaluated
537+
if (!std::is_constant_evaluated())
538+
#endif
539+
{
540+
__builtin_memset(__first,
541+
static_cast<unsigned char>(__value),
542+
__n);
543+
return __first + __n;
544+
}
545+
}
546+
539547
const auto __tmp = __value;
540548
for (; __n > 0; --__n, (void)++__first)
541549
*__first = __tmp;

libstdc++-v3/testsuite/25_algorithms/fill_n/constrained.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,12 @@ test01()
7373
}
7474
}
7575

76+
template<typename T>
7677
constexpr bool
7778
test02()
7879
{
7980
bool ok = true;
80-
int x[6] = { 1, 2, 3, 4, 5, 6 };
81+
T x[6] = { 1, 2, 3, 4, 5, 6 };
8182
const int y[6] = { 1, 2, 3, 4, 5, 6 };
8283
const int z[6] = { 17, 17, 17, 4, 5, 6 };
8384

@@ -94,5 +95,6 @@ int
9495
main()
9596
{
9697
test01();
97-
static_assert(test02());
98+
static_assert(test02<int>());
99+
static_assert(test02<unsigned char>()); // PR libstdc++/101608
98100
}

0 commit comments

Comments
 (0)