1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // REQUIRES: c++17 10 // <optional> 11 12 // constexpr optional(const optional<T>&& rhs); 13 // C++17 said: 14 // If is_trivially_move_constructible_v<T> is true, 15 // this constructor shall be a constexpr constructor. 16 // 17 // P0602 changed this to: 18 // If is_trivially_move_constructible_v<T> is true, this constructor is trivial. 19 // 20 // which means that it can't be constexpr if T is not trivially move-constructible, 21 // because you have to do a placement new to get the value into place. 22 // Except in the case where it is moving from an empty optional - that could be 23 // made to be constexpr (and libstdc++ does so). 24 25 #include <optional> 26 #include <type_traits> 27 #include <cassert> 28 29 #include "test_macros.h" 30 31 struct S { 32 constexpr S() : v_(0) {} 33 S(int v) : v_(v) {} 34 constexpr S(const S &rhs) : v_(rhs.v_) {} // not trivially moveable 35 constexpr S( S &&rhs) : v_(rhs.v_) {} // not trivially moveable 36 int v_; 37 }; 38 39 40 constexpr bool test() // expected-error {{constexpr function never produces a constant expression}} 41 { 42 std::optional<S> o1{3}; 43 std::optional<S> o2 = std::move(o1); 44 return o2.has_value(); // return -something- 45 } 46 47 48 int main(int, char**) 49 { 50 static_assert (!std::is_trivially_move_constructible_v<S>, "" ); 51 static_assert (test(), ""); // expected-error {{static_assert expression is not an integral constant expression}} 52 return 0; 53 } 54