[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