https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108775
Bug ID: 108775 Summary: Move construction clobbers data through [[no_unique_address]] Product: gcc Version: 12.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: danakj at orodu dot net Target Milestone: --- Clang also clobbers data in the same way: https://github.com/llvm/llvm-project/issues/60711 (MSVC does not) ``` #include <stdint.h> #include <iostream> #include <string> #include <vector> struct S2 { uint64_t a; }; struct S : public S2 { S(uint8_t b, uint64_t a) : S2(a), b(b) {} uint8_t b; // 3 bytes padding. }; static_assert(sizeof(S) == 16); union U { U() {} [[no_unique_address]] S s; }; static_assert(sizeof(U) == 16); struct D { D(uint8_t i) : i(i) {} [[no_unique_address]] U u; uint8_t i; }; static_assert(sizeof(D) == 16); int main() { D d(1u); std::cout << (int)d.i << "\n"; // Regular construction into `D::u` doesn't touch `D::i`. Good. new (&d.u.s) S(2, 3); std::cout << (int)d.i << "\n"; S s(4, 5); // Move construction into `D::u` overwrites `D::i`. Bad. new (&d.u.s) S(std::move(s)); std::cout << (int)d.i << "\n"; return d.i; } ``` Godbolt: https://godbolt.org/z/YzrM59E5a