PR libstdc++/85642 fix is_nothrow_default_constructible<optional<T>>
authorJonathan Wakely <jwakely@redhat.com>
Fri, 4 May 2018 08:57:23 +0000 (09:57 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 4 May 2018 08:57:23 +0000 (09:57 +0100)
Add missing noexcept keyword to default constructor of each
_Optional_payload specialization.

PR libstdc++/85642 fix is_nothrow_default_constructible<optional<T>>
* include/std/optional (_Optional_payload): Add noexcept to default
constructor. Re-indent.
(_Optional_payload<_Tp, true, true, true>): Likewise. Add noexcept to
constructor for copying disengaged payloads.
(_Optional_payload<_Tp, true, false, true>): Likewise.
(_Optional_payload<_Tp, true, true, false>): Likewise.
(_Optional_payload<_Tp, true, false, false>): Likewise.
* testsuite/20_util/optional/cons/85642.cc: New.
* testsuite/20_util/optional/cons/value_neg.cc: Adjust dg-error lines.

From-SVN: r259928

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/optional
libstdc++-v3/testsuite/20_util/optional/cons/85642.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc

index ed616dfa8f1a4ce1eff20e80f808ca717e210e3a..93935ab9787870db7c538bee3a0c45d97469bfb4 100644 (file)
@@ -1,3 +1,16 @@
+2018-05-04  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/85642 fix is_nothrow_default_constructible<optional<T>>
+       * include/std/optional (_Optional_payload): Add noexcept to default
+       constructor. Re-indent.
+       (_Optional_payload<_Tp, true, true, true>): Likewise. Add noexcept to
+       constructor for copying disengaged payloads.
+       (_Optional_payload<_Tp, true, false, true>): Likewise.
+       (_Optional_payload<_Tp, true, true, false>): Likewise.
+       (_Optional_payload<_Tp, true, false, false>): Likewise.
+       * testsuite/20_util/optional/cons/85642.cc: New.
+       * testsuite/20_util/optional/cons/value_neg.cc: Adjust dg-error lines.
+
 2018-05-03  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/82644
index 0aa20dd94374588d2f435e6a1d51a8f3a535f67b..746ee2fd87e44719bbcd87c698af4c132941a365 100644 (file)
@@ -82,8 +82,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
   public:
     bad_optional_access() { }
+
     virtual const char* what() const noexcept override
-    {return "bad optional access";}
+    { return "bad optional access"; }
 
     virtual ~bad_optional_access() noexcept = default;
   };
@@ -108,36 +109,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              is_trivially_move_assignable<_Tp>::value>
     struct _Optional_payload
     {
-      constexpr _Optional_payload()
-       : _M_empty() {}
+      constexpr _Optional_payload() noexcept : _M_empty() { }
 
       template <typename... _Args>
-      constexpr _Optional_payload(in_place_t, _Args&&... __args)
-       : _M_payload(std::forward<_Args>(__args)...),
-         _M_engaged(true) {}
+       constexpr
+       _Optional_payload(in_place_t, _Args&&... __args)
+       : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
 
       template<typename _Up, typename... _Args>
-      constexpr _Optional_payload(std::initializer_list<_Up> __il,
-                                 _Args&&... __args)
+       constexpr
+       _Optional_payload(std::initializer_list<_Up> __il,
+                         _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
-         _M_engaged(true) {}
+         _M_engaged(true)
+       { }
+
       constexpr
       _Optional_payload(bool __engaged, const _Optional_payload& __other)
-       : _Optional_payload(__other)
-      {}
+      : _Optional_payload(__other)
+      { }
 
       constexpr
       _Optional_payload(bool __engaged, _Optional_payload&& __other)
-       : _Optional_payload(std::move(__other))
-      {}
+      : _Optional_payload(std::move(__other))
+      { }
 
-      constexpr _Optional_payload(const _Optional_payload& __other)
+      constexpr
+      _Optional_payload(const _Optional_payload& __other)
       {
        if (__other._M_engaged)
          this->_M_construct(__other._M_payload);
       }
 
-      constexpr _Optional_payload(_Optional_payload&& __other)
+      constexpr
+      _Optional_payload(_Optional_payload&& __other)
       {
        if (__other._M_engaged)
          this->_M_construct(std::move(__other._M_payload));
@@ -176,7 +181,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       using _Stored_type = remove_const_t<_Tp>;
+
       struct _Empty_byte { };
+
       union {
           _Empty_byte _M_empty;
           _Stored_type _M_payload;
@@ -201,16 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // The _M_get operations have _M_engaged as a precondition.
       constexpr _Tp&
-       _M_get() noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() noexcept
+      { return this->_M_payload; }
 
       constexpr const _Tp&
-       _M_get() const noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() const noexcept
+      { return this->_M_payload; }
 
       // _M_reset is a 'safe' operation with no precondition.
       void
@@ -224,62 +227,64 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     };
 
-  // Payload for constexpr optionals.
+  // Payload for potentially-constexpr optionals.
   template <typename _Tp>
     struct _Optional_payload<_Tp, true, true, true>
     {
-      constexpr _Optional_payload()
-       : _M_empty(), _M_engaged(false) {}
+      constexpr _Optional_payload() noexcept
+      : _M_empty(), _M_engaged(false) { }
 
       template<typename... _Args>
-      constexpr _Optional_payload(in_place_t, _Args&&... __args)
-       : _M_payload(std::forward<_Args>(__args)...),
-         _M_engaged(true)
-      {}
+       constexpr
+       _Optional_payload(in_place_t, _Args&&... __args)
+       : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
+       { }
 
       template<typename _Up, typename... _Args>
-      constexpr _Optional_payload(std::initializer_list<_Up> __il,
-                                 _Args&&... __args)
+       constexpr
+       _Optional_payload(std::initializer_list<_Up> __il,
+                         _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
-         _M_engaged(true) {}
+         _M_engaged(true)
+       { }
 
       template <class _Up> struct __ctor_tag {};
 
-      constexpr _Optional_payload(__ctor_tag<bool>,
-                                 const _Tp& __other)
-       : _M_payload(__other),
-         _M_engaged(true)
-      {}
+      constexpr
+      _Optional_payload(__ctor_tag<bool>, const _Tp& __other)
+      : _M_payload(__other), _M_engaged(true)
+      { }
 
-      constexpr _Optional_payload(__ctor_tag<void>)
-       : _M_empty(), _M_engaged(false)
-      {}
+      constexpr _Optional_payload(__ctor_tag<void>) noexcept
+      : _M_empty(), _M_engaged(false)
+      { }
 
       constexpr _Optional_payload(__ctor_tag<bool>, _Tp&& __other)
-       : _M_payload(std::move(__other)),
-         _M_engaged(true)
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 const _Optional_payload& __other)
-       : _Optional_payload(__engaged ?
-                           _Optional_payload(__ctor_tag<bool>{},
-                                             __other._M_payload) :
-                           _Optional_payload(__ctor_tag<void>{}))
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 _Optional_payload&& __other)
-       : _Optional_payload(__engaged
-                           ? _Optional_payload(__ctor_tag<bool>{},
-                                               std::move(__other._M_payload))
-                           : _Optional_payload(__ctor_tag<void>{}))
-      {}
+      : _M_payload(std::move(__other)), _M_engaged(true)
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, const _Optional_payload& __other)
+      : _Optional_payload(__engaged ?
+                         _Optional_payload(__ctor_tag<bool>{},
+                                           __other._M_payload) :
+                         _Optional_payload(__ctor_tag<void>{}))
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, _Optional_payload&& __other)
+      : _Optional_payload(__engaged
+                         ? _Optional_payload(__ctor_tag<bool>{},
+                                             std::move(__other._M_payload))
+                         : _Optional_payload(__ctor_tag<void>{}))
+      { }
 
       using _Stored_type = remove_const_t<_Tp>;
+
       struct _Empty_byte { };
+
       union {
-          _Empty_byte _M_empty;
+         _Empty_byte _M_empty;
           _Stored_type _M_payload;
       };
       bool _M_engaged;
@@ -289,53 +294,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template <typename _Tp>
     struct _Optional_payload<_Tp, true, false, true>
     {
-      constexpr _Optional_payload()
-       : _M_empty(), _M_engaged(false) {}
+      constexpr _Optional_payload() noexcept
+      : _M_empty(), _M_engaged(false) { }
 
       template<typename... _Args>
-      constexpr _Optional_payload(in_place_t, _Args&&... __args)
-       : _M_payload(std::forward<_Args>(__args)...),
-         _M_engaged(true)
-      {}
+       constexpr
+       _Optional_payload(in_place_t, _Args&&... __args)
+       : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true)
+       { }
 
       template<typename _Up, typename... _Args>
-      constexpr _Optional_payload(std::initializer_list<_Up> __il,
-                                 _Args&&... __args)
+       constexpr
+       _Optional_payload(std::initializer_list<_Up> __il,
+                         _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
-         _M_engaged(true) {}
+         _M_engaged(true)
+       { }
 
       template <class _Up> struct __ctor_tag {};
 
-      constexpr _Optional_payload(__ctor_tag<bool>,
-                                 const _Tp& __other)
-       : _M_payload(__other),
-         _M_engaged(true)
-      {}
+      constexpr _Optional_payload(__ctor_tag<bool>, const _Tp& __other)
+      : _M_payload(__other),
+       _M_engaged(true)
+      { }
 
-      constexpr _Optional_payload(__ctor_tag<void>)
-       : _M_empty(), _M_engaged(false)
-      {}
+      constexpr _Optional_payload(__ctor_tag<void>) noexcept
+      : _M_empty(), _M_engaged(false)
+      { }
 
       constexpr _Optional_payload(__ctor_tag<bool>, _Tp&& __other)
-       : _M_payload(std::move(__other)),
-         _M_engaged(true)
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 const _Optional_payload& __other)
-       : _Optional_payload(__engaged ?
-                           _Optional_payload(__ctor_tag<bool>{},
-                                             __other._M_payload) :
-                           _Optional_payload(__ctor_tag<void>{}))
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 _Optional_payload&& __other)
-       : _Optional_payload(__engaged
-                           ? _Optional_payload(__ctor_tag<bool>{},
-                                               std::move(__other._M_payload))
-                           : _Optional_payload(__ctor_tag<void>{}))
-      {}
+      : _M_payload(std::move(__other)),
+       _M_engaged(true)
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, const _Optional_payload& __other)
+      : _Optional_payload(__engaged ?
+                         _Optional_payload(__ctor_tag<bool>{},
+                                           __other._M_payload) :
+                         _Optional_payload(__ctor_tag<void>{}))
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, _Optional_payload&& __other)
+      : _Optional_payload(__engaged
+                         ? _Optional_payload(__ctor_tag<bool>{},
+                                             std::move(__other._M_payload))
+                         : _Optional_payload(__ctor_tag<void>{}))
+      { }
 
       _Optional_payload(const _Optional_payload&) = default;
       _Optional_payload(_Optional_payload&&) = default;
@@ -359,7 +365,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       operator=(_Optional_payload&& __other) = default;
 
       using _Stored_type = remove_const_t<_Tp>;
+
       struct _Empty_byte { };
+
       union {
           _Empty_byte _M_empty;
           _Stored_type _M_payload;
@@ -378,16 +386,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // The _M_get operations have _M_engaged as a precondition.
       constexpr _Tp&
-       _M_get() noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() noexcept
+      { return this->_M_payload; }
 
       constexpr const _Tp&
-       _M_get() const noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() const noexcept
+      { return this->_M_payload; }
 
       // _M_reset is a 'safe' operation with no precondition.
       void
@@ -405,53 +409,56 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template <typename _Tp>
     struct _Optional_payload<_Tp, true, true, false>
     {
-      constexpr _Optional_payload()
-       : _M_empty(), _M_engaged(false) {}
+      constexpr _Optional_payload() noexcept
+      : _M_empty(), _M_engaged(false) { }
 
       template<typename... _Args>
-      constexpr _Optional_payload(in_place_t, _Args&&... __args)
+       constexpr
+       _Optional_payload(in_place_t, _Args&&... __args)
        : _M_payload(std::forward<_Args>(__args)...),
          _M_engaged(true)
-      {}
+       { }
 
       template<typename _Up, typename... _Args>
-      constexpr _Optional_payload(std::initializer_list<_Up> __il,
-                                 _Args&&... __args)
+       constexpr
+       _Optional_payload(std::initializer_list<_Up> __il,
+                         _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
-         _M_engaged(true) {}
+         _M_engaged(true)
+       { }
 
       template <class _Up> struct __ctor_tag {};
 
-      constexpr _Optional_payload(__ctor_tag<bool>,
-                                 const _Tp& __other)
-       : _M_payload(__other),
-         _M_engaged(true)
-      {}
+      constexpr
+      _Optional_payload(__ctor_tag<bool>, const _Tp& __other)
+      : _M_payload(__other),
+       _M_engaged(true)
+      { }
 
-      constexpr _Optional_payload(__ctor_tag<void>)
-       : _M_empty(), _M_engaged(false)
-      {}
+      constexpr _Optional_payload(__ctor_tag<void>) noexcept
+      : _M_empty(), _M_engaged(false)
+      { }
 
       constexpr _Optional_payload(__ctor_tag<bool>, _Tp&& __other)
-       : _M_payload(std::move(__other)),
-         _M_engaged(true)
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 const _Optional_payload& __other)
-       : _Optional_payload(__engaged ?
-                           _Optional_payload(__ctor_tag<bool>{},
-                                             __other._M_payload) :
-                           _Optional_payload(__ctor_tag<void>{}))
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 _Optional_payload&& __other)
-       : _Optional_payload(__engaged
-                           ? _Optional_payload(__ctor_tag<bool>{},
-                                               std::move(__other._M_payload))
-                           : _Optional_payload(__ctor_tag<void>{}))
-      {}
+      : _M_payload(std::move(__other)),
+       _M_engaged(true)
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, const _Optional_payload& __other)
+      : _Optional_payload(__engaged ?
+                         _Optional_payload(__ctor_tag<bool>{},
+                                           __other._M_payload) :
+                         _Optional_payload(__ctor_tag<void>{}))
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, _Optional_payload&& __other)
+      : _Optional_payload(__engaged
+                         ? _Optional_payload(__ctor_tag<bool>{},
+                                             std::move(__other._M_payload))
+                         : _Optional_payload(__ctor_tag<void>{}))
+      { }
 
       _Optional_payload(const _Optional_payload&) = default;
       _Optional_payload(_Optional_payload&&) = default;
@@ -477,7 +484,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       using _Stored_type = remove_const_t<_Tp>;
+
       struct _Empty_byte { };
+
       union {
           _Empty_byte _M_empty;
           _Stored_type _M_payload;
@@ -496,16 +505,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // The _M_get operations have _M_engaged as a precondition.
       constexpr _Tp&
-       _M_get() noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() noexcept
+      { return this->_M_payload; }
 
       constexpr const _Tp&
-       _M_get() const noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() const noexcept
+      { return this->_M_payload; }
 
       // _M_reset is a 'safe' operation with no precondition.
       void
@@ -523,53 +528,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template <typename _Tp>
     struct _Optional_payload<_Tp, true, false, false>
     {
-      constexpr _Optional_payload()
-       : _M_empty(), _M_engaged(false) {}
+      constexpr _Optional_payload() noexcept
+      : _M_empty(), _M_engaged(false) {}
 
       template<typename... _Args>
-      constexpr _Optional_payload(in_place_t, _Args&&... __args)
+       constexpr
+       _Optional_payload(in_place_t, _Args&&... __args)
        : _M_payload(std::forward<_Args>(__args)...),
          _M_engaged(true)
-      {}
+       { }
 
       template<typename _Up, typename... _Args>
-      constexpr _Optional_payload(std::initializer_list<_Up> __il,
-                                 _Args&&... __args)
+       constexpr
+       _Optional_payload(std::initializer_list<_Up> __il,
+                         _Args&&... __args)
        : _M_payload(__il, std::forward<_Args>(__args)...),
-         _M_engaged(true) {}
+         _M_engaged(true)
+       { }
 
       template <class _Up> struct __ctor_tag {};
 
-      constexpr _Optional_payload(__ctor_tag<bool>,
-                                 const _Tp& __other)
-       : _M_payload(__other),
-         _M_engaged(true)
-      {}
+      constexpr _Optional_payload(__ctor_tag<bool>, const _Tp& __other)
+      : _M_payload(__other),
+           _M_engaged(true)
+      { }
 
-      constexpr _Optional_payload(__ctor_tag<void>)
-       : _M_empty(), _M_engaged(false)
-      {}
+      constexpr _Optional_payload(__ctor_tag<void>) noexcept
+      : _M_empty(), _M_engaged(false)
+      { }
 
       constexpr _Optional_payload(__ctor_tag<bool>, _Tp&& __other)
-       : _M_payload(std::move(__other)),
-         _M_engaged(true)
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 const _Optional_payload& __other)
-       : _Optional_payload(__engaged ?
-                           _Optional_payload(__ctor_tag<bool>{},
-                                             __other._M_payload) :
-                           _Optional_payload(__ctor_tag<void>{}))
-      {}
-
-      constexpr _Optional_payload(bool __engaged,
-                                 _Optional_payload&& __other)
-       : _Optional_payload(__engaged
-                           ? _Optional_payload(__ctor_tag<bool>{},
-                                               std::move(__other._M_payload))
-                           : _Optional_payload(__ctor_tag<void>{}))
-      {}
+      : _M_payload(std::move(__other)),
+       _M_engaged(true)
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, const _Optional_payload& __other)
+      : _Optional_payload(__engaged ?
+                         _Optional_payload(__ctor_tag<bool>{},
+                                           __other._M_payload) :
+                         _Optional_payload(__ctor_tag<void>{}))
+      { }
+
+      constexpr
+      _Optional_payload(bool __engaged, _Optional_payload&& __other)
+      : _Optional_payload(__engaged
+                         ? _Optional_payload(__ctor_tag<bool>{},
+                                             std::move(__other._M_payload))
+                         : _Optional_payload(__ctor_tag<void>{}))
+      { }
 
       _Optional_payload(const _Optional_payload&) = default;
       _Optional_payload(_Optional_payload&&) = default;
@@ -607,7 +614,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       using _Stored_type = remove_const_t<_Tp>;
+
       struct _Empty_byte { };
+
       union {
           _Empty_byte _M_empty;
           _Stored_type _M_payload;
@@ -626,16 +635,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // The _M_get operations have _M_engaged as a precondition.
       constexpr _Tp&
-       _M_get() noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() noexcept
+      { return this->_M_payload; }
 
       constexpr const _Tp&
-       _M_get() const noexcept
-      {
-       return this->_M_payload;
-      }
+      _M_get() const noexcept
+      { return this->_M_payload; }
 
       // _M_reset is a 'safe' operation with no precondition.
       void
@@ -658,15 +663,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // The _M_construct operation has !_M_engaged as a precondition
       // while _M_destruct has _M_engaged as a precondition.
       template<typename... _Args>
-      void
-      _M_construct(_Args&&... __args)
+       void
+       _M_construct(_Args&&... __args)
        noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
-      {
-       ::new
-         (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
-         _Stored_type(std::forward<_Args>(__args)...);
-       static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
-      }
+       {
+         ::new
+           (std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
+           _Stored_type(std::forward<_Args>(__args)...);
+         static_cast<_Dp*>(this)->_M_payload._M_engaged = true;
+       }
       
       void
       _M_destruct() noexcept
@@ -700,8 +705,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : protected _Optional_base_impl<_Tp, _Optional_base<_Tp>>
     {
       friend class _Optional_base_impl<_Tp, _Optional_base<_Tp>>;
-    public:
 
+    public:
       // Constructors for disengaged optionals.
       constexpr _Optional_base() = default;
 
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/85642.cc b/libstdc++-v3/testsuite/20_util/optional/cons/85642.cc
new file mode 100644 (file)
index 0000000..4d366f1
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <optional>
+
+struct NonTrivialDtor {
+  ~NonTrivialDtor() { }
+};
+
+struct NonTrivialCopyAssign {
+  NonTrivialCopyAssign& operator=(const NonTrivialCopyAssign&) { return *this; }
+  NonTrivialCopyAssign& operator=(NonTrivialCopyAssign&&) = default;
+};
+
+struct NonTrivialMoveAssign {
+  NonTrivialMoveAssign& operator=(const NonTrivialMoveAssign&) = default;
+  NonTrivialMoveAssign& operator=(NonTrivialMoveAssign&&) { return *this; }
+};
+
+struct NonTrivialAssign {
+  NonTrivialAssign& operator=(const NonTrivialAssign&) { return *this; }
+  NonTrivialAssign& operator=(NonTrivialAssign&&) { return *this; }
+};
+
+struct NonTrivialAll {
+  ~NonTrivialAll() { }
+  NonTrivialAll& operator=(const NonTrivialAll&) { return *this; }
+  NonTrivialAll& operator=(NonTrivialAll&&) { return *this; }
+};
+
+struct ConstExpr { int i = 0; };
+
+struct Trivial { int i; };
+
+template<typename T>
+  constexpr bool check
+    = std::is_nothrow_default_constructible_v<std::optional<T>>;
+
+// PR libstdc++/85642
+static_assert(check<NonTrivialDtor>);
+static_assert(check<NonTrivialCopyAssign>);
+static_assert(check<NonTrivialMoveAssign>);
+static_assert(check<NonTrivialAssign>);
+static_assert(check<NonTrivialAll>);
+static_assert(check<ConstExpr>);
+static_assert(check<Trivial>);
index ae55ab233f1e5339f1ee6d4e205add406c94bcf5..e9171ef7cc2a4ecd872574a0d1d6293a77da64f0 100644 (file)
@@ -37,8 +37,8 @@ int main()
     std::optional<std::unique_ptr<int>> oup2 = new int;  // { dg-error "conversion" }
     struct U { explicit U(std::in_place_t); };
     std::optional<U> ou(std::in_place); // { dg-error "no matching" }
-    // { dg-error "no type" "" { target { *-*-* } } 1015 }
-    // { dg-error "no type" "" { target { *-*-* } } 1025 }
-    // { dg-error "no type" "" { target { *-*-* } } 1082 }
+    // { dg-error "no type" "" { target { *-*-* } } 1020 }
+    // { dg-error "no type" "" { target { *-*-* } } 1030 }
+    // { dg-error "no type" "" { target { *-*-* } } 1087 }
   }
 }