libstdc++: Remove __memmove wrapper for constexpr algorithms
The mutating sequence algorithms std::copy, std::copy_backward,
std::move and std::move_backward conditionally use __builtin_memmove
for trivially copyable types. However, because memmove isn't usable in
constant expressions the use of __builtin_memmove is wrapped in a
__memmove function which replaces __builtin_memmove with a handwritten
loop when std::is_constant_evaluated() is true.
This means we have a manual loop for non-trivially copyable cases, and a
different manual loop for trivially copyable but constexpr cases. The
latter loop has incorrect semantics for the {copy,move}_backward cases
and so isn't used for them. Until earlier today the latter loop also had
incorrect semantics for the std::move cases, trying to move from const
rvalues.
The approach taken by this patch is to remove the __memmove function
entirely and use the original (and correct) manual loops for the
constexpr cases as well as the non-trivially copyable cases. This was
already done for move_backward and copy_backward, but was incorrectly
turning copy_backward into move_backward, by failing to use the _IsMove
constant to select the right specialization. This patch also fixes that.
* include/bits/ranges_algobase.h (__copy_or_move): Do not use memmove
during constant evaluation. Call __builtin_memmove directly instead of
__memmove.
(__copy_or_move_backward): Likewise.
* include/bits/stl_algobase.h (__memmove): Remove.
(__copy_move<M, true, random_access_iterator_tag>::__copy_m)
(__copy_move_backward<M, true, random_access_iterator_tag>::__copy_m):
Use __builtin_memmove directly instead of __memmove.
(__copy_move_a2): Do not use memmove during constant evaluation.
(__copy_move_backward_a2): Use _IsMove constant to select correct
__copy_move_backward specialization.
* testsuite/25_algorithms/copy_backward/constexpr.cc: Check for copies
begin turned into moves during constant evaluation.