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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Philipp Ochsendorf from comment #0)
> I think the following decision is too restrictive:
> 
> return std::__uninitialized_copy<__is_trivial(_ValueType1)
>                             && __is_trivial(_ValueType2)
>                             && __assignable>::
>       __uninit_copy(__first, __last, __result);
> 
> (cf. stl_uninitialized.h:123ff). The following should be sufficient:
> 
> return std::__uninitialized_copy<is_trivially_copyable(_ValueType1)
>                             && is_trivially_copyable(_ValueType2)
>                             && __assignable>::
>       __uninit_copy(__first, __last, __result);
> 
> Found this in 5.2.0 and 6.0. Probably it's in versions prior to 5.2.0 as
> well.

This is not OK. It would do the wrong thing for:

struct X { X() { } };

That type is not trivial, and so in uninitialized_copy we loop and invoke copy
constructors to initialize each element. Everything is good.

With the suggestion above we would start using std::copy, which would just use
assignment to copy objects, but no constructor would ever have run so the
object's lifetime would not have started, and we'd be doing an assignment
(admittedly a trivial one, but that doesn't matter) to raw memory, not an
object.

Ville is working on a correct fix, but it is much more involved than just
changing the condition shown above.

Reply via email to