https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103040
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So the question is what is different between the C++ and D version. In C++17, RVO is mandatory, NRVO is an optimization, but guess one could add a copy constructor that would set impl to this and copy over x from the argument's ->x, then regardless of whether NRVO happens or not the observable result should be the same. Like: struct S101273 { int x; S101273* impl; S101273(int x) { this->x = x; this->impl = this; } S101273(const S101273 &o) { this->x = o.x; this->impl = this; } ~S101273() { } }; S101273 makeS101273() { return S101273(2); } S101273 nrvo101273() { S101273 ret = makeS101273(); return ret; } S101273 rvo101273() { return makeS101273(); } int main() { auto nrvo = nrvo101273(); if(&nrvo != nrvo.impl) __builtin_abort (); auto rvo = rvo101273(); if(&rvo != rvo.impl) __builtin_abort (); return 0; } But that isn't miscompiled at -O1 either.