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.