[llvm-dev] Placement new and TBAA

Hubert Tong via llvm-dev llvm-dev at lists.llvm.org
Sat Nov 26 11:14:34 PST 2016


On Fri, Nov 25, 2016 at 11:23 PM, Mehdi Amini <mehdi.amini at apple.com> wrote:

> You don’t need the main and the union to reproduce, extracting foo() alone
> in its single own file is enough:
>
> void *operator new(decltype(sizeof 0), void *) noexcept;
> float *qq;
> void foo(int *p, int *q, long unk) {
>    for (long i = 0; i < unk; ++i) {
>       ++*p;
>       qq = new (static_cast<void *>(&q[i])) float(42);
>    }
> }
>
> LICM will get the store to p out of the loop, conceptually turning it into:
>
> void foo(int *p, int *q, long unk) {
>    for (long i = 0; i < unk; ++i) {
>       qq = new (static_cast<void *>(&q[i])) float(42);
>    }
>    ++*p;
> }
>
>
> Now I don’t know if the use of placement new in this example is legal in
> the first place. I thought calling delete before using placement new was
> mandatory.
>
There's wording describing the reuse of storage and the situation of
neither calling the destructor nor using a *delete-expression*.

N4604 subclause 3.8 [basic.life] paragraph 5:

For an object of a class type with a non-trivial destructor, the program is
not required to call the destructor explicitly before the storage which the
object occupies is reused or released; however, if there is no explicit
call to the destructor or if a *delete-expression* is not used to release
the storage, the destructor shall not be implicitly called and any program
that depends on the side effects produced by the destructor has undefined
behavior.

I read the above wording as saying that, even if the storage is currently
occupied by an object of class type with a non-trivial destructor, the
storage can be "simply" reused (without undefined behaviour). The lifetime
of the previous object simply ends when the placement new occurs (more
wording below).

3.8 [basic.life] paragraph 1:

The lifetime of an object *o* of type T ends when [ ... ] the storage which
the object occupies is released, or is reused by an object that is not
nested within *o*.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161126/3a2e2e19/attachment.html>


More information about the llvm-dev mailing list