130862412SMarshall Clow //===----------------------------------------------------------------------===// 230862412SMarshall Clow // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630862412SMarshall Clow // 730862412SMarshall Clow //===----------------------------------------------------------------------===// 830862412SMarshall Clow 954644993SChristopher Di Bella // REQUIRES: c++17 1030862412SMarshall Clow // <optional> 1130862412SMarshall Clow 1230862412SMarshall Clow // constexpr optional(const optional<T>&& rhs); 1307161d6dSMarshall Clow // C++17 said: 1430862412SMarshall Clow // If is_trivially_move_constructible_v<T> is true, 1530862412SMarshall Clow // this constructor shall be a constexpr constructor. 1607161d6dSMarshall Clow // 1707161d6dSMarshall Clow // P0602 changed this to: 1807161d6dSMarshall Clow // If is_trivially_move_constructible_v<T> is true, this constructor is trivial. 1907161d6dSMarshall Clow // 2007161d6dSMarshall Clow // which means that it can't be constexpr if T is not trivially move-constructible, 2107161d6dSMarshall Clow // because you have to do a placement new to get the value into place. 2207161d6dSMarshall Clow // Except in the case where it is moving from an empty optional - that could be 2307161d6dSMarshall Clow // made to be constexpr (and libstdc++ does so). 2430862412SMarshall Clow 2530862412SMarshall Clow #include <optional> 2630862412SMarshall Clow #include <type_traits> 2730862412SMarshall Clow #include <cassert> 2830862412SMarshall Clow 2930862412SMarshall Clow #include "test_macros.h" 3030862412SMarshall Clow 3130862412SMarshall Clow struct S { SS3230862412SMarshall Clow constexpr S() : v_(0) {} SS3330862412SMarshall Clow S(int v) : v_(v) {} SS3430862412SMarshall Clow constexpr S(const S &rhs) : v_(rhs.v_) {} // not trivially moveable SS3507161d6dSMarshall Clow constexpr S( S &&rhs) : v_(rhs.v_) {} // not trivially moveable 3630862412SMarshall Clow int v_; 3730862412SMarshall Clow }; 3830862412SMarshall Clow 3930862412SMarshall Clow test()4007161d6dSMarshall Clowconstexpr bool test() // expected-error {{constexpr function never produces a constant expression}} 4107161d6dSMarshall Clow { 4207161d6dSMarshall Clow std::optional<S> o1{3}; 4307161d6dSMarshall Clow std::optional<S> o2 = std::move(o1); 4407161d6dSMarshall Clow return o2.has_value(); // return -something- 4507161d6dSMarshall Clow } 4607161d6dSMarshall Clow 4707161d6dSMarshall Clow main(int,char **)482df59c50SJF Bastienint main(int, char**) 4930862412SMarshall Clow { 5030862412SMarshall Clow static_assert (!std::is_trivially_move_constructible_v<S>, "" ); 51*76476efdSMuhammad Usman Shahid static_assert (test(), ""); // expected-error-re {{{{(static_assert|static assertion)}} expression is not an integral constant expression}} 522df59c50SJF Bastien return 0; 5330862412SMarshall Clow } 54