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

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 16 14:51:01 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>


ldionne wrote:

Is [this](https://godbolt.org/z/qo6GnMoxx) code valid?

```
using E = int;
using T = std::optional<int>;

void f(std::expected<T, E>& e) {
    assert(e.has_value());
    T& val = *e;
    val.~T();
    std::construct_at(&val, T{}); // this still overwrites has_value 
}
```

If so, then it means that the basic issue has to do with any place where we use `[[no_unique_address]]` and where we escape a reference to our subobject to users (which is the case for `__val_` and `__unex_`).

If the code above is not valid, then the dual fix of adding padding after our own `bool __has_value_` and making sure we "overwrite" the `bool` after initializing the union member would seem to work, but it's extremely unclean to the point of me wondering whether we're using the language feature as it was intended.

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


More information about the libcxx-commits mailing list