On Tue, Oct 18, 2016 at 1:06 PM, Jakub Jelinek 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
> 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