On Mon, Jan 28, 2019 at 8:52 AM Jonathan Wakely <jwak...@redhat.com> wrote: > > On 28/01/19 14:29 +0100, Jakub Jelinek wrote: > >On Mon, Jan 28, 2019 at 01:55:38PM +0100, Richard Biener wrote: > >> So I guess in the end we're being lucky. Somehow. I've played with > >> > >> __attribute__((noipa)) void > >> qux () > >> { > >> S buf1; > >> foo ((char *)&buf1); > >> S *p = new (&buf1) (S); > >> bar (p); > >> p->~S (); > >> { > >> char buf2[128]; > >> baz (buf2); > >> } > >> } > > > >I'd think the above is already invalid, by doing a placement new into > >a variable with non-trivial ctor and dtor while it is still constructed, > >then destruct the placement new created var in there and after a while > >destruct the original variable doesn't feel right to me, but I'm not a C++ > > Right. When the second object is constructed in that location, the > lifetime of the first one ends. When the destructor is automatically > run at the end of the scope you're destroying something that is no > longer alive, so undefined.
Indeed. > >language lawyer. I'd expect that usually either the whole var has > >char/std::byte etc. array type, or the placement new is into a field inside > >of some class (again char/std::byte etc. array type). > >Would could be valid is: > > Yeah I think the one below is OK. I'm still looking at the original > testcase at the top of the thread. The original testcase looks good to me. And I agree with Jakub's point, that destroying an object created in a buffer is necessarily different from destroying the buffer itself. Jason