[libcxx-commits] [libcxx] 088c7f7 - [libc++] Applies P0602R4 retro-actively.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 20 10:01:43 PDT 2022


Author: Mark de Wever
Date: 2022-09-20T19:01:34+02:00
New Revision: 088c7f7e3ce8d702b6d7b69a362ceb9a4f91a569

URL: https://github.com/llvm/llvm-project/commit/088c7f7e3ce8d702b6d7b69a362ceb9a4f91a569
DIFF: https://github.com/llvm/llvm-project/commit/088c7f7e3ce8d702b6d7b69a362ceb9a4f91a569.diff

LOG: [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

Added: 
    

Modified: 
    libcxx/include/optional
    libcxx/include/variant
    libcxx/test/std/utilities/optional/optional.object/optional.object.assign/copy.pass.cpp
    libcxx/test/std/utilities/optional/optional.object/optional.object.assign/move.pass.cpp
    libcxx/test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp
    libcxx/test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp
    libcxx/test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp
    libcxx/test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp

Removed: 
    libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.fail.cpp


################################################################################
diff  --git a/libcxx/include/optional b/libcxx/include/optional
index e9286ea1824f5..126b85532b88f 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 <class... Args> constexpr explicit optional(in_place_t, Args &&...);
     template <class U, class... Args>
       constexpr explicit optional(in_place_t, initializer_list<U>, 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 <class U = T> optional &operator=(U &&);            // constexpr in C++20
     template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
     template <class U> optional &operator=(optional<U> &&);      // 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 <class _Up = value_type,

diff  --git a/libcxx/include/variant b/libcxx/include/variant
index afb861f81243a..7e2bea3ae7a9d 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -22,8 +22,8 @@ namespace std {
 
     // 20.7.2.1, constructors
     constexpr variant() noexcept(see below);
-    variant(const variant&);                // constexpr in C++20
-    variant(variant&&) noexcept(see below); // constexpr in C++20
+    constexpr variant(const variant&);
+    constexpr variant(variant&&) noexcept(see below);
 
     template <class T> 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 <class T> 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 c5cfb4ccc42f5..9753fdb46b862 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>
 
-// optional<T>& operator=(const optional<T>& rhs); // constexpr in C++20
+// constexpr optional<T>& operator=(const optional<T>& rhs);
 
 #include <optional>
 #include <type_traits>
@@ -53,19 +53,15 @@ int main(int, char**)
 {
     {
         using O = optional<int>;
-#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<TrivialTestTypes::TestType>;
-#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 1f47d552993e4..85971e38f7b70 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>
 
-// optional<T>& operator=(optional<T>&& rhs)
+// constexpr optional<T>& operator=(optional<T>&& rhs)
 //     noexcept(is_nothrow_move_assignable<T>::value &&
-//              is_nothrow_move_constructible<T>::value); // constexpr in C++20
+//              is_nothrow_move_constructible<T>::value);
 
 #include <optional>
 #include <cassert>
@@ -114,19 +114,15 @@ int main(int, char**)
     }
     {
         using O = optional<int>;
-#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<TrivialTestTypes::TestType>;
-#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 4df41120d7e31..0000000000000
--- 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
-// <optional>
-
-// constexpr optional(const optional<T>&& rhs);
-//  C++17 said:
-//   If is_trivially_move_constructible_v<T> is true,
-//    this constructor shall be a constexpr constructor.
-//
-//  P0602 changed this to:
-//     If is_trivially_move_constructible_v<T> 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 <optional>
-#include <type_traits>
-#include <cassert>
-
-#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<S> o1{3};
-    std::optional<S> o2 = std::move(o1);
-    return o2.has_value();  // return -something-
-}
-
-
-int main(int, char**)
-{
-    static_assert (!std::is_trivially_move_constructible_v<S>, "" );
-    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 3d0d14af19171..46ccd44096653 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 ...Types> class variant;
 
-// variant& operator=(variant const&); // constexpr in C++20
+// constexpr variant& operator=(variant const&);
 
 #include <cassert>
 #include <string>
@@ -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<int, long>;
     static_assert(std::is_trivially_copy_assignable<V>::value, "");
@@ -252,7 +251,6 @@ void test_copy_assignment_sfinae() {
     using V = std::variant<int, CopyOnly>;
     static_assert(std::is_trivially_copy_assignable<V>::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<int> 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_
diff erent_index() {
@@ -524,7 +520,6 @@ void test_copy_assignment_
diff erent_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<long> operator()() const {
@@ -553,7 +548,6 @@ void test_copy_assignment_
diff erent_index() {
     static_assert(result.index == 1, "");
     static_assert(result.value == 42, "");
   }
-#endif // > C++17
 }
 
 template <size_t NewIdx, class ValueType>
@@ -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<long, void*, int>;
   static_assert(std::is_trivially_copyable<V>::value, "");
   static_assert(std::is_trivially_copy_assignable<V>::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 a3c939765dd9b..775330f8bf71a 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 ...Types> class variant;
 
-// variant& operator=(variant&&) noexcept(see below); // constexpr in C++20
+// constexpr variant& operator=(variant&&) noexcept(see below);
 
 #include <cassert>
 #include <string>
@@ -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<int, long>;
     static_assert(std::is_trivially_move_assignable<V>::value, "");
@@ -221,7 +220,6 @@ void test_move_assignment_sfinae() {
     using V = std::variant<int, CopyOnly>;
     static_assert(std::is_trivially_move_assignable<V>::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<int> 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_
diff erent_index() {
@@ -438,7 +434,6 @@ void test_move_assignment_
diff erent_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<long> operator()() const {
@@ -467,7 +462,6 @@ void test_move_assignment_
diff erent_index() {
     static_assert(result.index == 1, "");
     static_assert(result.value == 42, "");
   }
-#endif // > C++17
 }
 
 template <size_t NewIdx, class ValueType>
@@ -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<long, void*, int>;
   static_assert(std::is_trivially_copyable<V>::value, "");
   static_assert(std::is_trivially_move_assignable<V>::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 3fdfcbb07f3b0..f0d539c9914a8 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 ...Types> class variant;
 
-// variant(variant const&); // constexpr in C++20
+// constexpr variant(variant const&);
 
 #include <cassert>
 #include <type_traits>
@@ -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<int, long>;
     static_assert(std::is_trivially_copy_constructible<V>::value, "");
@@ -138,7 +137,6 @@ void test_copy_ctor_sfinae() {
     using V = std::variant<int, TCopyNTMove>;
     static_assert(std::is_trivially_copy_constructible<V>::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<int> 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<long, void*, const int>
 
 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<long, void*, const int>;
 #ifdef TEST_WORKAROUND_MSVC_BROKEN_IS_TRIVIALLY_COPYABLE
   static_assert(std::is_trivially_destructible<V>::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 7d2ce7c50d904..1c67f020d1107 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 ...Types> class variant;
 
-// variant(variant&&) noexcept(see below); // constexpr in C++20
+// constexpr variant(variant&&) noexcept(see below);
 
 #include <cassert>
 #include <string>
@@ -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<int, long>;
     static_assert(std::is_trivially_move_constructible<V>::value, "");
@@ -159,7 +158,6 @@ void test_move_ctor_sfinae() {
     using V = std::variant<int, TMoveNTCopy>;
     static_assert(std::is_trivially_move_constructible<V>::value, "");
   }
-#endif // > C++17
 }
 
 template <typename T>
@@ -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<int> 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<long, void*, const int> 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<long, void*, const int>;
 #ifdef TEST_WORKAROUND_MSVC_BROKEN_IS_TRIVIALLY_COPYABLE
   static_assert(std::is_trivially_destructible<V>::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**) {


        


More information about the libcxx-commits mailing list