On Tue, Oct 18, 2016 at 1:06 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> http://wg21.link/p0137
> adds std::launder which is supposed to be some kind of aliasing optimization
> barrier.
>
> What is unclear to me is if we really need compiler support for that.
> I have unfortunately not found many examples:
>
> http://stackoverflow.com/questions/39382501/what-is-the-purpose-of-stdlaunder
> mentions something like:
> #include <new>
> int
> foo ()
> {
>   struct X { const int n; };
>   union U { X x; float f; };
>   U u = {{ 1 }};
>   int a = u.x.n;
>   X *p = new (&u.x) X {2};
>   int b = u.x.n;        // UB, needs std::launder(&u.x.n)
>   return a + b;
> }
> but g++ handles it as returning 3 even without that.
> So, do we need to do anything here even in the current gcc aliasing model,
> which is very permissive (my understanding is that usually we treat all
> writes as possibly placement new-ish changes)?

The standard mentions that appearantly const and reference "sub-objects" are
unchanging when you access them.  Cruically they changed 3.8/1 to

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 ([intro.object])

the subobject notion is new.  I suppse this was done to formally allow
construction of objects
in char[] members w/o ending the containings object lifetime.  I think
this is somewhat of a mistake
as obviously two (sub-)objects can't be life at the same time at the
same memory location
(which the undefined behavior above implies).

And yes, GCC doesn't need anything special as it handles sub-object
lifetime properly
(any store may end it) and it doesn't exploit the "constness" of const
declared members
or reference members.

> Then I found something like:
> https://groups.google.com/a/isocpp.org/forum/#!msg/std-discussion/XYvVlTc3-to/HbhebSRnAgAJ
> which of course doesn't work with -flifetime-dse=2, I'd strongly hope that
> all those attempts there are UB even with std::launder.

Obviously std::launder now invites people to invent fancy things (all
UB), similar
to how reinterpret_cast<>s name invited people to think it has anything to do
with TBAA.

std::launder is about object lifetime, nothing else IIUC.

> Adding __builtin_launder as void * -> void * builtin (ECF_CONST) or perhaps
> typegeneric one that returns the same pointer as given to it (and not
> teaching alias analysis about what that builtin does) is certainly possible,
> the question is how to expand it at RTL time (does it also need to be some
> kind of opt barrier, say like __asm ("" : "+g" (ptr));, or not?

As said, nothing needed for the middle-end.

Richard.

>         Jakub

Reply via email to