On Thu, 4 Jun 2020 at 11:53, Marc Glisse <marc.gli...@inria.fr> wrote: > > On Thu, 4 Jun 2020, Ville Voutilainen wrote: > > > On Thu, 4 Jun 2020 at 11:00, Marc Glisse <marc.gli...@inria.fr> wrote: > >> Maybe create a buffer, fill it with some non-zero values (-1?), then call > >> placement new, and read some value in the middle of the buffer, possibly > >> with some protection against optimizations? Ah, no, actual constructors > >> are fine, it is only the inlined initialization that happens with the > >> defaulted constructor that zeroes things. > > > > The zero-init is part of value-initialization of a class type with a > > defaulted default constructor, so value-initialization with placement > > new should indeed show us whether the target buffer is zeroed. > > Ah, yes, I had forgotten the empty () at the end of the operator new line > when testing. Now the patch makes this runtime test go from abort to > success at -O0 (with optimizations, the memset is removed as dead code). I > am still not sure we want this kind of test though. And I added launder > more to quiet a warning than with confidence that it does the right thing. > > #include <optional> > struct A { > int a[1024]; > }; > typedef std::optional<A> O; > int main(){ > unsigned char t[sizeof(O)]; > __builtin_memset(t, -1, sizeof(t)); > new(t)O(); > if(std::launder(t)[512] != (unsigned char)(-1)) __builtin_abort(); > }
Yeah, I think the patch is OK with or without the test. As a side note, you don't need the launder if the check uses the pointer value returned by placement-new.