Skip to content

Commit

Permalink
libstdc++: Do not use memset in constexpr calls to ranges::fill_n [PR…
Browse files Browse the repository at this point in the history
…101608]

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)
  • Loading branch information
jwakely committed Nov 25, 2021
1 parent 88b9997 commit 7ae6e4e
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
28 changes: 18 additions & 10 deletions libstdc++-v3/include/bits/ranges_algobase.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,17 +525,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;
Expand Down
6 changes: 4 additions & 2 deletions libstdc++-v3/testsuite/25_algorithms/fill_n/constrained.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand All @@ -94,5 +95,6 @@ int
main()
{
test01();
static_assert(test02());
static_assert(test02<int>());
static_assert(test02<unsigned char>()); // PR libstdc++/101608
}

0 comments on commit 7ae6e4e

Please sign in to comment.