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

Jason Merrill jason at redhat.com
Thu Jul 21 20:20:07 UTC 2016


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.

> 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


More information about the cxx-abi-dev mailing list