[libcxx-commits] [libcxx] [libc++] Fix UB in <expected> related to "has value" flag (#68552) (PR #68733)
Jan Kokemüller via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Oct 17 07:22:35 PDT 2023
================
@@ -136,14 +134,7 @@ class expected {
noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened
requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> &&
!(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>))
- : __has_val_(__other.__has_val_) {
- if (__has_val_) {
- std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_);
- } else {
- std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_);
- }
- }
-
+ : __union_(__union_from_expected(__other)), __has_val_(__other.__has_val_) { }
----------------
jiixyj wrote:
It turns out that GCC 13 didn't like this approach:
```txt
_bk;t=1697372498369# | In file included from /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1/expected:44,
_bk;t=1697372498369# | from /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp:28:
_bk;t=1697372498369# | /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1/__expected/expected.h: In instantiation of ‘constexpr std::__1::expected<_Tp, _Err>::expected(const std::__1::expected<_Tp, _Err>&) requires (is_copy_constructible_v<_Tp>) && (is_copy_constructible_v<_Err>) && !((is_trivially_copy_constructible_v<_Tp>) && (is_trivially_copy_constructible_v<_Err>)) [with _Tp = testException()::Throwing; _Err = int]’:
_bk;t=1697372498369# | /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.copy.pass.cpp:112:34: required from here
_bk;t=1697372498369# | /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1/__expected/expected.h:137:9: error: use of deleted function ‘std::__1::expected<testException()::Throwing, int>::__union_t<testException()::Throwing, int>::__union_t(const std::__1::expected<testException()::Throwing, int>::__union_t<testException()::Throwing, int>&)’
_bk;t=1697372498369# | 137 | : __union_(__union_from_expected(__other)), __has_val_(__other.__has_val_) { }
_bk;t=1697372498369# | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_bk;t=1697372498369# | /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1/__expected/expected.h:860:9: note: ‘std::__1::expected<testException()::Throwing, int>::__union_t<testException()::Throwing, int>::__union_t(const std::__1::expected<testException()::Throwing, int>::__union_t<testException()::Throwing, int>&)’ is implicitly deleted because the default definition would be ill-formed:
_bk;t=1697372498369# | 860 | union __union_t {
_bk;t=1697372498369# | | ^~~~~~~~~
_bk;t=1697372498369# | /home/libcxx-builder/.buildkite-agent/builds/google-libcxx-builder-5c70ceab5f4e-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1/__expected/expected.h:888:16: error: union member ‘std::__1::expected<testException()::Throwing, int>::__union_t<testException()::Throwing, int>::__val_’ with non-trivial ‘testException()::Throwing::Throwing(const testException()::Throwing&)’
_bk;t=1697372498369# | 888 | _ValueType __val_;
_bk;t=1697372498369# | | ^~~~~~
```
I now added constructors to the `__union_t` as @huixie90 suggested. Let's see if the CI succeeds...
https://github.com/llvm/llvm-project/pull/68733
More information about the libcxx-commits
mailing list