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

Richard Smith richardsmith at googlers.com
Thu Jul 21 18:45:16 UTC 2016


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.

(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, 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.)

At this point I'm questioning the wisdom of allowing a virtual base to be
allocated into tail padding.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20160721/3808b4bd/attachment.html>


More information about the cxx-abi-dev mailing list