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