[libcxx-commits] [libcxx] [libc++] Fix UB in <expected> related to "has value" flag (#68552) (PR #68733)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 16 13:50:12 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>
Message-ID:
In-Reply-To: <llvm/llvm-project/pull/68733/libcxx at github.com>


philnik777 wrote:

> > I implemented the proposed (ABI changing) fix [here](https://github.com/jiixyj/llvm-project/commit/922895055cf3e31b4f3b2b89c990cec4e30ec429) and all tests pass! With that patch `expected` has no longer any tail padding, so `std::construct_at`/`std::destroy_at` wouldn't be able to overwrite any important data (except for `__has_value_`, but that is always restored correctly).
> 
> Is the following valid user code? If so, we will still have a problem
> 
> ```
> std::expected<T, E> e = ...;
> T& val = *e;
> val.~T();
> std::construct_at(&val, args...); // this still overwrites has_value
> ```

I don't know for certain, but I don't think that's valid. You can't expect that everything works if you have a potentially overlapping subobject and then destroy and construct it. Constructing and destroying only subobjects is quite tricky in general (as we can see from the bugs here).

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


More information about the libcxx-commits mailing list