Move construction clobbers data through [[no_unique_address]] · Issue #60711 · llvm/llvm-project (original) (raw)

Skip to content

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

@danakj

Description

@danakj

Godbolt: https://godbolt.org/z/e96axcv1b

#include <stdint.h>

#include #include #include

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"; // Prints 1

// Regular construction into `D::u` doesn't touch `D::i`. Good.
new (&d.u.s) S(2, 3);
std::cout << (int)d.i << "\n";  // Prints 1

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";  // Prints 0
return d.i;

}