[cxx-abi-dev] Guaranteed copy elision and tail padding

Richard Smith richardsmith at googlers.com
Thu Jul 21 20:31:59 UTC 2016


On 21 July 2016 at 13:20, Jason Merrill <jason at redhat.com> wrote:

> On Thu, Jul 21, 2016 at 2:45 PM, Richard Smith
> <richardsmith at googlers.com> wrote:
> > On 21 July 2016 at 11:02, Jason Merrill <jason at redhat.com> wrote:
> >>
> >> P0135 seems to require that we elide the copy when using the result of
> >> a function returning by value to initialize a base class subobject,
> >> but the ABI doesn't currently require that such a function avoid
> >> clobbering tail padding when initializing its return object.
> >> Thoughts?
> >
> > If the function clobbers the tail padding of its return object, at least
> GCC
> > and Clang will miscompile the program today, without P0135:
> >
> > #include <string.h>
> > struct X { ~X() {} int n; char d; };
> > struct Y { Y(); char c[3]; };
> > struct Z : X, virtual Y { Z(); };
> >
> > X f() { X nrvo; memset(&nrvo, 0, sizeof(X)); return nrvo; }
> > Z::Z() : Y(), X(f()) {}
> > Y::Y() : c{1, 2, 3} {}
> >
> > int main() {
> >   Z z;
> >   return z.c[0];
> > }
> >
> > GCC -O0 returns 1 from main, as it should. GCC -O2 and Clang (any
> > optimization level, even with -fno-elide-constructors) returns 0.
>
> Thanks for the testcase.
>
> > (It looks like Clang gets this "wrong" in two ways: first, NRVO is
> apprently
> > never correct on a type whose tail padding could be reused
>
> Hmm, I was thinking that the NRVO was fine, but the caller shouldn't
> elide the copy because the function might clobber tail padding.  But
> that gets back to my initial question, since P0135 requires that
> elision.  Avoiding NRVO here doesn't conflict with P0135, but it does
> create a new ABI requirement that existing code might violate.


Given John's observation that P0135 can't even work in theory for the case
of a base class with virtual bases, it seems like disabling P0135 for the
case of initializing a base class of a class with vbases may be the
simplest way forward.

> and second, we
> > assume that we can memcpy a trivially-copyable base class at its full
> size
> > -- effectively, we seem to assume that we won't initialize the tail
> padding
> > of a base class before we initialize the base class itself.)
>
> And I'd fixed that in one place already, but still needed to fix it in
> another.
>
> > At this point I'm questioning the wisdom of allowing a virtual base to be
> > allocated into tail padding.
>
> Yep.
>
> Jason
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20160721/58d796ca/attachment.html>


More information about the cxx-abi-dev mailing list