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

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Dec 22 10:46:33 PST 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>,
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.org/llvm/llvm-project/pull/69673 at github.com>


================
@@ -88,8 +88,289 @@ _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
 #  endif
----------------
ldionne wrote:

We should add a release note. Let's start with something like this:

> The amount of padding bytes available for use at the end of certain ``std::expected`` instantiations has changed in this release. This is an ABI break for any code that held a ``std::expected`` member *with ``[[no_unique_address]]``* in an ABI-facing type. In those cases, the layout of the enclosing type will change, breaking the ABI. However, the ``std::expected<T, E>`` member requires a few characteristics in order to be affected by this change:
> 1. A type equivalent to ``union {T ; E}`` needs to have more than one byte of padding available.
> 2. The ``std::expected<T, E>`` member must have been in a situation where its padding bytes were previously reused by another object, which can happen in a few cases (this is probably not exhaustive):
>   - It is a member with ``[[no_unique_address]]`` applied to it, and it is followed by another data member, or
>   - It is a member with ``[[no_unique_address]]`` applied to it, and it is the last member of the user-defined type, and that user-defined type is used in ways that its padding bytes can be reused, or
>   - It is inherited from
> 
> We expect that this will not be a very frequent occurrence. However, there is unfortunately to technique we can use in the library to catch such misuse. Indeed, even applying an ABI tag to ``std::expected`` would not help since ABI tags are not propagated to containing types. As a result, if you notice very difficult to explain bugs around the usage of a ``std::expected``, you should consider checking whether you are hitting this ABI break.


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


More information about the libcxx-commits mailing list