https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121180

--- Comment #8 from Halalaluyafail3 <luigighiron at gmail dot com> ---
Thinking about it again, base classes aren't even required to create the issue
of two overlapping objects with the same type:

struct S{
    unsigned char x[4];
};
static_assert(sizeof(S)==4);
S s;
S*p=::new((void*)s.x)S;

s.x can provide storage for an object of 4 bytes or less and an alignment
requirement no more than alignof(S). So if S has no padding then s.x can
provide storage for another S object. So two S objects would exist, one nested
inside the other. Or maybe because transparent replacement there is one S
object where its own member provides storage for it? It's not clear if calling
the destructors would be valid:

p->~S();
s.~S();

If this is valid, the behavior of std::launder also seems unclear:

std::launder((S*)s.x)->~S();

There are two objects that would make sense for launder to return, so there is
no clear way to determine which object was destroyed. Or perhaps there being
two objects that would make sense to return violates the preconditions of
launder. These issues with how overlapping objects of the same type work seem
to imply that this was never intended to be possible. So it would make sense
for std::any to avoid creating objects in itself when this issue can arise.
  • [Bug libstdc++/121180] std::any ... luigighiron at gmail dot com via Gcc-bugs

Reply via email to