[Bug libstdc++/68350] std::uninitialized_copy overly restrictive for trivially_copyable types

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Dec 16 17:01:00 GMT 2015


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.


More information about the Gcc-bugs mailing list