From: Mark de Wever Date: Mon, 5 Sep 2022 17:01:50 +0000 (+0200) Subject: [libc++] Applies P0602R4 retro-actively. X-Git-Tag: upstream/17.0.6~33008 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=088c7f7e3ce8d702b6d7b69a362ceb9a4f91a569;p=platform%2Fupstream%2Fllvm.git [libc++] Applies P0602R4 retro-actively. While testing a test failure of C++17 with Clang ToT it was noticed the paper P0602R4 variant and optional should propagate copy/move triviality was not applied as a DR in libc++. This was discovered while investigating the issue "caused by" D131479. Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D133326 --- diff --git a/libcxx/include/optional b/libcxx/include/optional index e9286ea..126b855 100644 --- a/libcxx/include/optional +++ b/libcxx/include/optional @@ -87,8 +87,8 @@ namespace std { // 23.6.3.1, constructors constexpr optional() noexcept; constexpr optional(nullopt_t) noexcept; - optional(const optional &); - optional(optional &&) noexcept(see below); + constexpr optional(const optional &); + constexpr optional(optional &&) noexcept(see below); template constexpr explicit optional(in_place_t, Args &&...); template constexpr explicit optional(in_place_t, initializer_list, Args &&...); @@ -104,8 +104,8 @@ namespace std { // 23.6.3.3, assignment optional &operator=(nullopt_t) noexcept; // constexpr in C++20 - optional &operator=(const optional &); // constexpr in C++20 - optional &operator=(optional &&) noexcept(see below); // constexpr in C++20 + constexpr optional &operator=(const optional &); + constexpr optional &operator=(optional &&) noexcept(see below); template optional &operator=(U &&); // constexpr in C++20 template optional &operator=(const optional &); // constexpr in C++20 template optional &operator=(optional &&); // constexpr in C++20 @@ -818,8 +818,8 @@ public: return *this; } - _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default; - _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default; + constexpr optional& operator=(const optional&) = default; + constexpr optional& operator=(optional&&) = default; // LWG2756 template constexpr variant(T&&) noexcept(see below); @@ -45,8 +45,8 @@ namespace std { ~variant(); // 20.7.2.3, assignment - variant& operator=(const variant&); // constexpr in C++20 - variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 + constexpr variant& operator=(const variant&); + constexpr variant& operator=(variant&&) noexcept(see below); template variant& operator=(T&&) noexcept(see below); @@ -1305,8 +1305,8 @@ public: constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) : __impl_(in_place_index<0>) {} - variant(const variant&) = default; - variant(variant&&) = default; + constexpr variant(const variant&) = default; + constexpr variant(variant&&) = default; template < class _Arg, @@ -1377,8 +1377,8 @@ public: ~variant() = default; - variant& operator=(const variant&) = default; - variant& operator=(variant&&) = default; + constexpr variant& operator=(const variant&) = default; + constexpr variant& operator=(variant&&) = default; template < class _Arg, diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp index c5cfb4c..9753fdb 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp @@ -9,7 +9,7 @@ // UNSUPPORTED: c++03, c++11, c++14 // -// optional& operator=(const optional& rhs); // constexpr in C++20 +// constexpr optional& operator=(const optional& rhs); #include #include @@ -53,19 +53,15 @@ int main(int, char**) { { using O = optional; -#if TEST_STD_VER > 17 - LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); - LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); -#endif + static_assert(assign_empty(O{42})); + static_assert(assign_value(O{42})); assert(assign_empty(O{42})); assert(assign_value(O{42})); } { using O = optional; -#if TEST_STD_VER > 17 - LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); - LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); -#endif + static_assert(assign_empty(O{42})); + static_assert(assign_value(O{42})); assert(assign_empty(O{42})); assert(assign_value(O{42})); } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp index 1f47d55..85971e3 100644 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp @@ -9,9 +9,9 @@ // UNSUPPORTED: c++03, c++11, c++14 // -// optional& operator=(optional&& rhs) +// constexpr optional& operator=(optional&& rhs) // noexcept(is_nothrow_move_assignable::value && -// is_nothrow_move_constructible::value); // constexpr in C++20 +// is_nothrow_move_constructible::value); #include #include @@ -114,19 +114,15 @@ int main(int, char**) } { using O = optional; -#if TEST_STD_VER > 17 - LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); - LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); -#endif + static_assert(assign_empty(O{42})); + static_assert(assign_value(O{42})); assert(assign_empty(O{42})); assert(assign_value(O{42})); } { using O = optional; -#if TEST_STD_VER > 17 - LIBCPP_STATIC_ASSERT(assign_empty(O{42}), ""); - LIBCPP_STATIC_ASSERT(assign_value(O{42}), ""); -#endif + static_assert(assign_empty(O{42})); + static_assert(assign_value(O{42})); assert(assign_empty(O{42})); assert(assign_value(O{42})); } diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.fail.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.fail.cpp deleted file mode 100644 index 4df4112..0000000 --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.fail.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// REQUIRES: c++17 -// - -// constexpr optional(const optional&& rhs); -// C++17 said: -// If is_trivially_move_constructible_v is true, -// this constructor shall be a constexpr constructor. -// -// P0602 changed this to: -// If is_trivially_move_constructible_v is true, this constructor is trivial. -// -// which means that it can't be constexpr if T is not trivially move-constructible, -// because you have to do a placement new to get the value into place. -// Except in the case where it is moving from an empty optional - that could be -// made to be constexpr (and libstdc++ does so). - -#include -#include -#include - -#include "test_macros.h" - -struct S { - constexpr S() : v_(0) {} - S(int v) : v_(v) {} - constexpr S(const S &rhs) : v_(rhs.v_) {} // not trivially moveable - constexpr S( S &&rhs) : v_(rhs.v_) {} // not trivially moveable - int v_; - }; - - -constexpr bool test() // expected-error {{constexpr function never produces a constant expression}} -{ - std::optional o1{3}; - std::optional o2 = std::move(o1); - return o2.has_value(); // return -something- -} - - -int main(int, char**) -{ - static_assert (!std::is_trivially_move_constructible_v, "" ); - static_assert (test(), ""); // expected-error-re {{{{(static_assert|static assertion)}} expression is not an integral constant expression}} - return 0; -} diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp index 3d0d14a..46ccd44 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp @@ -15,7 +15,7 @@ // template class variant; -// variant& operator=(variant const&); // constexpr in C++20 +// constexpr variant& operator=(variant const&); #include #include @@ -230,7 +230,6 @@ void test_copy_assignment_sfinae() { } // Make sure we properly propagate triviality (see P0602R4). -#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_copy_assignable::value, ""); @@ -252,7 +251,6 @@ void test_copy_assignment_sfinae() { using V = std::variant; static_assert(std::is_trivially_copy_assignable::value, ""); } -#endif // > C++17 } void test_copy_assignment_empty_empty() { @@ -376,7 +374,6 @@ void test_copy_assignment_same_index() { #endif // TEST_HAS_NO_EXCEPTIONS // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -433,7 +430,6 @@ void test_copy_assignment_same_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } -#endif // > C++17 } void test_copy_assignment_different_index() { @@ -524,7 +520,6 @@ void test_copy_assignment_different_index() { #endif // TEST_HAS_NO_EXCEPTIONS // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -553,7 +548,6 @@ void test_copy_assignment_different_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } -#endif // > C++17 } template @@ -569,7 +563,6 @@ constexpr bool test_constexpr_assign_imp( void test_constexpr_copy_assignment() { // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 using V = std::variant; static_assert(std::is_trivially_copyable::value, ""); static_assert(std::is_trivially_copy_assignable::value, ""); @@ -577,7 +570,6 @@ void test_constexpr_copy_assignment() { static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), ""); static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), ""); static_assert(test_constexpr_assign_imp<2>(V(42l), 101), ""); -#endif // > C++17 } int main(int, char**) { diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp index a3c9397..775330f 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp @@ -15,7 +15,7 @@ // template class variant; -// variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 +// constexpr variant& operator=(variant&&) noexcept(see below); #include #include @@ -195,7 +195,6 @@ void test_move_assignment_sfinae() { } // Make sure we properly propagate triviality (see P0602R4). -#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_move_assignable::value, ""); @@ -221,7 +220,6 @@ void test_move_assignment_sfinae() { using V = std::variant; static_assert(std::is_trivially_move_assignable::value, ""); } -#endif // > C++17 } void test_move_assignment_empty_empty() { @@ -344,7 +342,6 @@ void test_move_assignment_same_index() { #endif // TEST_HAS_NO_EXCEPTIONS // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -387,7 +384,6 @@ void test_move_assignment_same_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } -#endif // > C++17 } void test_move_assignment_different_index() { @@ -438,7 +434,6 @@ void test_move_assignment_different_index() { #endif // TEST_HAS_NO_EXCEPTIONS // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -467,7 +462,6 @@ void test_move_assignment_different_index() { static_assert(result.index == 1, ""); static_assert(result.value == 42, ""); } -#endif // > C++17 } template @@ -484,7 +478,6 @@ constexpr bool test_constexpr_assign_imp( void test_constexpr_move_assignment() { // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 using V = std::variant; static_assert(std::is_trivially_copyable::value, ""); static_assert(std::is_trivially_move_assignable::value, ""); @@ -492,7 +485,6 @@ void test_constexpr_move_assignment() { static_assert(test_constexpr_assign_imp<0>(V(nullptr), 101l), ""); static_assert(test_constexpr_assign_imp<1>(V(42l), nullptr), ""); static_assert(test_constexpr_assign_imp<2>(V(42l), 101), ""); -#endif // > C++17 } int main(int, char**) { diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp index 3fdfcbb..f0d539c9 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp @@ -15,7 +15,7 @@ // template class variant; -// variant(variant const&); // constexpr in C++20 +// constexpr variant(variant const&); #include #include @@ -120,7 +120,6 @@ void test_copy_ctor_sfinae() { } // Make sure we properly propagate triviality (see P0602R4). -#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_copy_constructible::value, ""); @@ -138,7 +137,6 @@ void test_copy_ctor_sfinae() { using V = std::variant; static_assert(std::is_trivially_copy_constructible::value, ""); } -#endif // > C++17 } void test_copy_ctor_basic() { @@ -170,7 +168,6 @@ void test_copy_ctor_basic() { } // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 { constexpr std::variant v(std::in_place_index<0>, 42); static_assert(v.index() == 0, ""); @@ -213,7 +210,6 @@ void test_copy_ctor_basic() { static_assert(v2.index() == 1, ""); static_assert(std::get<1>(v2).value == 42, ""); } -#endif // > C++17 } void test_copy_ctor_valueless_by_exception() { @@ -237,7 +233,6 @@ constexpr bool test_constexpr_copy_ctor_imp(std::variant void test_constexpr_copy_ctor() { // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 using V = std::variant; #ifdef TEST_WORKAROUND_MSVC_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_destructible::value, ""); @@ -251,7 +246,6 @@ void test_constexpr_copy_ctor() { static_assert(test_constexpr_copy_ctor_imp<0>(V(42l)), ""); static_assert(test_constexpr_copy_ctor_imp<1>(V(nullptr)), ""); static_assert(test_constexpr_copy_ctor_imp<2>(V(101)), ""); -#endif // > C++17 } int main(int, char**) { diff --git a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp index 7d2ce7c..1c67f02 100644 --- a/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp +++ b/libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp @@ -15,7 +15,7 @@ // template class variant; -// variant(variant&&) noexcept(see below); // constexpr in C++20 +// constexpr variant(variant&&) noexcept(see below); #include #include @@ -141,7 +141,6 @@ void test_move_ctor_sfinae() { } // Make sure we properly propagate triviality (see P0602R4). -#if TEST_STD_VER > 17 { using V = std::variant; static_assert(std::is_trivially_move_constructible::value, ""); @@ -159,7 +158,6 @@ void test_move_ctor_sfinae() { using V = std::variant; static_assert(std::is_trivially_move_constructible::value, ""); } -#endif // > C++17 } template @@ -210,7 +208,6 @@ void test_move_ctor_basic() { } // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 { struct { constexpr Result operator()() const { @@ -283,7 +280,6 @@ void test_move_ctor_basic() { static_assert(result.index == 1, ""); static_assert(result.value.value == 42, ""); } -#endif // > C++17 } void test_move_ctor_valueless_by_exception() { @@ -307,7 +303,6 @@ constexpr bool test_constexpr_ctor_imp(std::variant cons void test_constexpr_move_ctor() { // Make sure we properly propagate triviality, which implies constexpr-ness (see P0602R4). -#if TEST_STD_VER > 17 using V = std::variant; #ifdef TEST_WORKAROUND_MSVC_BROKEN_IS_TRIVIALLY_COPYABLE static_assert(std::is_trivially_destructible::value, ""); @@ -322,7 +317,6 @@ void test_constexpr_move_ctor() { static_assert(test_constexpr_ctor_imp<0>(V(42l)), ""); static_assert(test_constexpr_ctor_imp<1>(V(nullptr)), ""); static_assert(test_constexpr_ctor_imp<2>(V(101)), ""); -#endif // > C++17 } int main(int, char**) {