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

Reply via email to