<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/56741>56741</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
`std::copy` forwards to `memmove` in too many cases
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
philnik777
</td>
</tr>
</table>
<pre>
`std::copy` forwards to `memmove` with a `move_iterator` even if the type isn't `trivially_move_assignable`.
Here is a reproducer:
```c++
struct TriviallyCopyableNotTriviallyMovable {
bool* move_assigned_;
TEST_CONSTEXPR_CXX20 TriviallyCopyableNotTriviallyMovable() = default;
TEST_CONSTEXPR_CXX20 TriviallyCopyableNotTriviallyMovable(bool* move_assigned) : move_assigned_(move_assigned) {}
TEST_CONSTEXPR_CXX20 TriviallyCopyableNotTriviallyMovable(const TriviallyCopyableNotTriviallyMovable&) = default;
TEST_CONSTEXPR_CXX20 TriviallyCopyableNotTriviallyMovable(TriviallyCopyableNotTriviallyMovable&&) = default;
TEST_CONSTEXPR_CXX20 TriviallyCopyableNotTriviallyMovable&
operator=(const TriviallyCopyableNotTriviallyMovable&) = default;
TEST_CONSTEXPR_CXX20 TriviallyCopyableNotTriviallyMovable& operator=(TriviallyCopyableNotTriviallyMovable&&) {
*move_assigned_ = true;
return *this;
}
};
static_assert(std::is_trivially_copy_assignable<TriviallyCopyableNotTriviallyMovable>::value, "");
static_assert(!std::is_trivially_move_assignable<TriviallyCopyableNotTriviallyMovable>::value, "");
TEST_CONSTEXPR_CXX20 bool test_move() {
bool move_assigned[10] {};
TriviallyCopyableNotTriviallyMovable from[10]{};
TriviallyCopyableNotTriviallyMovable to[10]{
{move_assigned + 0},
{move_assigned + 1},
{move_assigned + 2},
{move_assigned + 3},
{move_assigned + 4},
{move_assigned + 5},
{move_assigned + 6},
{move_assigned + 7},
{move_assigned + 8},
{move_assigned + 9}};
std::copy(std::begin(from), std::end(from), std::begin(to));
struct IsMoveAssigned {
TEST_CONSTEXPR_CXX20 bool operator()(bool b) { return b; }
};
assert(std::all_of(std::begin(move_assigned), std::end(move_assigned), IsMoveAssigned()));
return true;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVk2P2jAQ_TXOxSpyHPJ1yIGPXbWHbqvuHvaGktiAW4OR7bDi33ccSAiQVbMVlSpZkHieZ54nM88uFDtkKCLGMhRMYJRqd4B3vFT6LdfMYKswvG_4ZqP23FnehF3jvJ6EmYWwXOdWaWfie77FYontmmN72HEszBbR2Dqw1WIvcikPi3pZboxYbfNCOp8jROaITI6_n7l2CyGE5jutWFVy7bgdIRE5jhLRqRudhcbqqrT4pQk0g624AE_KtnNf1d5NYRSflmJcKCURneAOLc4WKGgBLw_PL4vZt6fnl4fX7z8Ws9dXSgZFQTRBNMUomGPGl3kl7Z289lI-hrrZB01uUbD5eH4PIqXammEZRzT6N7kYHPzd-HdgETU-1O7UDcH8v0hPdMXog9k6dwnGUHCXpVWzhZ7jHaoYmtZWeuvQdi1Mx9SWnHsIrjo3t6J0nrm2wLJVI2EWZ91w0tTVjWA2aDfBw9HXPpdAlc6AGq1H2rK4jo-o30_hWrruR-H42_ulXbdjy42twzeicilgV1IQTn2CwnnT6Z1SGiKOS602jYu_82BVd31bG64IphdMIRNTTFwEOvsjzh-IowNxwUDceCAuHIiLBuLigbhkIC51uJvmw_jy8O-0X8FXAg7wpC4IKFao3NbGt-wdS7MKisBZrmvcxasP6i8GyoVPWobdSnm_EVo9q_vgdBji4tQTjfwUEBR3Drm-bd_KDZTwQi37MnB9hvakog9yucWGcm9STsQv9PQsmZeXH49nfhQmSZRQ4nssC1gapLlnhZX8g7c5ASGVwpt8e8BlbrjxKi2ztbU741zQRxgruPFVxah0n_pRyn3z9wmuZz95CSl8FMZU3MBDGMVj31tnnDBGfBax0g-ZD4Wy9KOCpGnMkjJhLPJkXnBpMtAJUEIpiuZCB7IYzj2RUUIpiWlEyTjw0xHxwyCkY5oG4TIgSYzGhG9yIUeOyEjplaezmlNRrQwYpTDWnI2n78LreOA_r-xa6Wy3FnIrfsVx7NU7yGr6vwE5L2jS">