From f1a4db51fc0a639d1720bcb0b3a531b83a26b742 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 27 May 2023 09:36:21 +0800 Subject: [PATCH 1/8] Implement LWG-3843 (workaround) Also speculatively generalize the resolution to `expected`. --- stl/inc/expected | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/stl/inc/expected b/stl/inc/expected index 8c0fe0960f..aaa6280661 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -636,6 +636,12 @@ public: _Throw_bad_expected_access_lv(); } _NODISCARD constexpr const _Ty&& value() const&& { + // TRANSITION, DevCom-1638273 and LLVM-53224 + static_assert( + is_copy_constructible_v<_Err>, "is_copy_constructible_v must be true. N4950 [expected.object.obs]/11"); + static_assert(is_move_constructible_v<_Err>, + "is_constructible_v must be true. N4950 [expected.object.obs]/11"); + if (_Has_value) { return _STD move(_Value); } @@ -643,6 +649,12 @@ public: _Throw_bad_expected_access_rv(); } _NODISCARD constexpr _Ty&& value() && { + // TRANSITION, DevCom-1638273 and LLVM-53224 + static_assert( + is_copy_constructible_v<_Err>, "is_copy_constructible_v must be true. N4950 [expected.object.obs]/11"); + static_assert( + is_move_constructible_v<_Err>, "is_constructible_v must be true. N4950 [expected.object.obs]/11"); + if (_Has_value) { return _STD move(_Value); } @@ -1133,9 +1145,6 @@ private: [[noreturn]] void _Throw_bad_expected_access_lv() const { _THROW(bad_expected_access{_Unexpected}); } - [[noreturn]] void _Throw_bad_expected_access_lv() { - _THROW(bad_expected_access{_Unexpected}); - } [[noreturn]] void _Throw_bad_expected_access_rv() const { _THROW(bad_expected_access{_STD move(_Unexpected)}); } @@ -1414,6 +1423,11 @@ public: } } constexpr void value() && { + // per LWG issue unnumbered as of 2023-05-26 + // TRANSITION, DevCom-1638273 and LLVM-53224 + static_assert(is_copy_constructible_v<_Err>, "is_copy_constructible_v must be true"); + static_assert(is_move_constructible_v<_Err>, "is_move_constructible_v must be true"); + if (!_Has_value) { _Throw_bad_expected_access_rv(); } From 060075513dc5e62eed0560f0d868df423a556d36 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 27 May 2023 09:37:41 +0800 Subject: [PATCH 2/8] Test LWG-3843 --- tests/std/tests/P0323R12_expected/test.cpp | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index 546077a1ea..91214c634f 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -2060,6 +2060,81 @@ struct Data { }; static_assert(((void) expected{unexpect, {1, 2, 3}}, true)); +void test_lwg_3843() { + struct Indicator { + Indicator() = default; + + Indicator(Indicator& other) noexcept : count(other.count + 256) {} + Indicator(const Indicator& other) noexcept : count(other.count + 1024) {} + + Indicator(Indicator&& other) noexcept : count(other.count + 1) {} + Indicator(const Indicator&& other) noexcept : count(other.count + 16) {} + + Indicator& operator=(const Indicator&) = default; + Indicator& operator=(Indicator&&) = default; + + int count = 0; + }; + + { + expected exv{unexpect}; + assert(exv.error().count == 0); + + try { + (void) exv.value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 1025); + } + + try { + (void) as_const(exv).value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 1025); + } + + try { + (void) move(exv).value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 2); + } + + try { + (void) move(as_const(exv)).value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 17); + } + } + + { + expected exv{unexpect}; + assert(exv.error().count == 0); + + try { + (void) exv.value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 1025); + } + + try { + (void) as_const(exv).value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 1025); + } + + try { + (void) move(exv).value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 2); + } + + try { + (void) move(as_const(exv)).value(); + } catch (const bad_expected_access& e) { + assert(e.error().count == 1025); + } + } +} + int main() { test_unexpected::test_all(); static_assert(test_unexpected::test_all()); @@ -2075,4 +2150,5 @@ int main() { static_assert(is_convertible_v*, exception*>); test_reinit_regression(); + test_lwg_3843(); } From dd4073e9f3d5beda9990e6dc2344c4e95aa4eb1c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 27 May 2023 11:46:31 +0800 Subject: [PATCH 3/8] Skip one libcxx test --- tests/libcxx/expected_results.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index f4b0183639..85d42a04d6 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -152,6 +152,9 @@ std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitia std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp FAIL std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp FAIL +# libc++ doesn't implement LWG-3843 +std/utilities/expected/expected.expected/observers/value.pass.cpp + # libc++ doesn't implement P1957R2 "Converting from `T*` to `bool` should be considered narrowing" std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp FAIL std/utilities/variant/variant.variant/variant.assign/T.pass.cpp FAIL From 5dacb66637f4bb21e3146db00d3bfaeacb6c0ec7 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 27 May 2023 11:47:29 +0800 Subject: [PATCH 4/8] Missed FAIL! --- tests/libcxx/expected_results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 85d42a04d6..7c13a63959 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -153,7 +153,7 @@ std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitiali std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp FAIL # libc++ doesn't implement LWG-3843 -std/utilities/expected/expected.expected/observers/value.pass.cpp +std/utilities/expected/expected.expected/observers/value.pass.cpp FAIL # libc++ doesn't implement P1957R2 "Converting from `T*` to `bool` should be considered narrowing" std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp FAIL From b95c5f017c89a3155296c88da0ac413c2c2a4237 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 27 May 2023 12:09:49 +0800 Subject: [PATCH 5/8] Another skipping --- tests/libcxx/expected_results.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 7c13a63959..80b41a40b1 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -154,6 +154,7 @@ std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitiali # libc++ doesn't implement LWG-3843 std/utilities/expected/expected.expected/observers/value.pass.cpp FAIL +std/utilities/expected/expected.void/observers/value.pass.cpp FAIL # libc++ doesn't implement P1957R2 "Converting from `T*` to `bool` should be considered narrowing" std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp FAIL From ea096c154197535e8b15da29faea75d09b59493e Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 May 2023 16:39:20 +0800 Subject: [PATCH 6/8] The new issue is now LWG-3940 --- stl/inc/expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/expected b/stl/inc/expected index aaa6280661..d478e148bb 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -1423,7 +1423,7 @@ public: } } constexpr void value() && { - // per LWG issue unnumbered as of 2023-05-26 + // per LWG-3940 // TRANSITION, DevCom-1638273 and LLVM-53224 static_assert(is_copy_constructible_v<_Err>, "is_copy_constructible_v must be true"); static_assert(is_move_constructible_v<_Err>, "is_move_constructible_v must be true"); From b3d0c953023e1ddbcb84218cfcd863b2c16cfdb2 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 28 May 2023 17:22:06 +0800 Subject: [PATCH 7/8] Reference LWG-3940 in expected_results.txt --- tests/libcxx/expected_results.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 80b41a40b1..4c39a78d07 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -131,6 +131,9 @@ std/ranges/range.factories/range.iota.view/iterator/member_typedefs.compile.pass # libc++ doesn't implement LWG-3836 std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp FAIL +# libc++ doesn't implement LWG-3843 +std/utilities/expected/expected.expected/observers/value.pass.cpp FAIL + # libc++ doesn't implement LWG-3857 std/strings/string.view/string.view.cons/from_range.pass.cpp FAIL std/strings/string.view/string.view.cons/from_string1.compile.fail.cpp FAIL @@ -152,8 +155,7 @@ std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitia std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp FAIL std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp FAIL -# libc++ doesn't implement LWG-3843 -std/utilities/expected/expected.expected/observers/value.pass.cpp FAIL +# libc++ doesn't speculatively implement LWG-3940 std/utilities/expected/expected.void/observers/value.pass.cpp FAIL # libc++ doesn't implement P1957R2 "Converting from `T*` to `bool` should be considered narrowing" From be9583d459d17192306d8ae1300c5986fcb3e70d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Mon, 29 May 2023 07:10:06 +0800 Subject: [PATCH 8/8] Fix copy pasta --- stl/inc/expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/expected b/stl/inc/expected index d478e148bb..e87b4b0973 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -639,7 +639,7 @@ public: // TRANSITION, DevCom-1638273 and LLVM-53224 static_assert( is_copy_constructible_v<_Err>, "is_copy_constructible_v must be true. N4950 [expected.object.obs]/11"); - static_assert(is_move_constructible_v<_Err>, + static_assert(is_constructible_v<_Err, const _Err&&>, "is_constructible_v must be true. N4950 [expected.object.obs]/11"); if (_Has_value) {