[libcxx-commits] [libcxx] [libc++] Annotate the data member of variant with no_unique_address (PR #137783)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat May 3 02:05:47 PDT 2025


https://github.com/huixie90 requested changes to this pull request.

I am not sure if you are aware of the bug that we had in `std::expected`, where we applied `no_unique_address` to the union. The bug was that, every time we `emplace`, the `construct_at` will *zero initialise* the tail padding of the union, erasing anything that lives in the tail padding of  the union of `T` or `Err`, including the discriminator and any other user data if the user chose to `no_unique_address` of the whole `expected`.

We ended up have to ABI break to fix `expected`. (only conditionally apply `no_unique_address` and do not allow user's type to fit into's `union`'s tail padding). We only allow the user data to reuse padding when the discriminator is not in the tail padding of the `union` (meaning the `emplace` will not touch the user data)

I think this `variant` case is quite similar and just wanted to double check if you have thought about this. 

so to test this case, we want something that is big enough to fit our index type into the tail padding of T

```cpp
struct F {
    F(){} // to make it not a c-struct 
    long double c{};
    bool b{};
};

struct S {
 [[no_unique_address]] std::variant<int, F> v;
  bool b;
}


S s{};
s.b = true;
s.v.emplace<F>(......);

assert(s.b)

https://github.com/llvm/llvm-project/pull/137783


More information about the libcxx-commits mailing list