diff options
-rw-r--r-- | libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/move.fail.cpp | 25 |
1 files changed, 20 insertions, 5 deletions
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 index a8634b961c7..8aae55738f7 100644 --- 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 @@ -10,8 +10,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> @@ -23,16 +32,22 @@ struct S { constexpr S() : v_(0) {} S(int v) : v_(v) {} constexpr S(const S &rhs) : v_(rhs.v_) {} // not trivially moveable - 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>, "" ); - constexpr std::optional<S> o1; - constexpr std::optional<S> o2 = std::move(o1); // not constexpr - - return 0; + static_assert (test(), ""); // expected-error {{static_assert expression is not an integral constant expression}} + return 0; } |