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 {
SS32 constexpr S() : v_(0) {}
SS33 S(int v) : v_(v) {}
SS34 constexpr S(const S &rhs) : v_(rhs.v_) {} // not trivially moveable
SS35 constexpr S( S &&rhs) : v_(rhs.v_) {} // not trivially moveable
36 int v_;
37 };
38
39
test()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
main(int,char **)48 int main(int, char**)
49 {
50 static_assert (!std::is_trivially_move_constructible_v<S>, "" );
51 static_assert (test(), ""); // expected-error-re {{{{(static_assert|static assertion)}} expression is not an integral constant expression}}
52 return 0;
53 }
54