[llvm] [libc++] Ensure that `std::expected` has no tail padding (PR #69673)

A. Jiang via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 21 03:12:17 PDT 2023


Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>,
Jan =?utf-8?q?Kokemüller?= <jan.kokemueller at gmail.com>
Message-ID:
In-Reply-To: <llvm/llvm-project/pull/69673/llvm at github.com>


frederick-vs-ja wrote:

> > If you don't want to rely on a language extension, the rule you need to conform to is that you can't transparently replace a potentially overlapping subboject -- you can't use `construct_at` on a base class or a `[[no_unique_address]]` member.
> 
> Here's one approach you could take:
> 
> ```
> template<typename T, typename E> struct expected {
>   struct repr_type {
>     [[no_unique_address]] union {
>       [[no_unique_address]] T value;
>       [[no_unique_address]] E error;
>     };
>     bool is_error;
>   } repr;
> };
> ```
> 
> ... then apply `std::construct_at` to the `repr` member from `emplace`.

It seems that such strategy will make the tail padding of `expected<int, int>` unreusable...

Perhaps we should use a mixed strategy:
- when the `bool` flag lives in the tail padding of the union, the repr strategy should be used, and `expected` shouldn't have reusable tail padding,
- otherwise, however, we should make the tail padding of `expected` (if any) reusable.

It's painful that we have no `[[no_unique_address(condition)]]` yet.

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


More information about the llvm-commits mailing list