https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121789

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Avi Kivity from comment #2)
> (testq/jle sequence)
> 
> The jle itself is from libstdc++:

Ah right.

> I believe it's undefined to have __last not be reachable by incrementing
> __first, so != would be fine here.

Yes, but that was an intentional choice to limit the damage caused by user
mistakes.

If the user somehow gets their arguments wrong, we can either use memcpy to
read+write outside of bounds, or trap on __last < __first, or do nothing.

> Or not comparing and calling memcpy()
> directly (which I see first compares against a bunch of small values before
> detecting zero, I can't make up my mind if it's better to check in libstdc++
> or not).

That would be undefined for the case of std::uninitialized_move_(it, it, (T*)0)
because calling memcpy with a null pointer is UB (at least for C++23 and all
previous standards).

So at a minimum we need to check __first != __last to ensure we don't call
memcpy with a null pointer, and if we have to check that anyway then my
thinking was that we might as well also avoid accessing out of bounds for the
buggy case where __last < __first.

Reply via email to