diff mbox series

PR libstdc++/85642 fix is_nothrow_default_constructible<optional<T>>

Message ID 20180504085655.GA12379@redhat.com
State New
Headers show
Series PR libstdc++/85642 fix is_nothrow_default_constructible<optional<T>> | expand

Commit Message

Jonathan Wakely May 4, 2018, 8:56 a.m. UTC
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.

I've also re-indented the _Optional_payload code to ensure that
everything after a template-head is indented and a ctor-initializer is
lined up with the start of the constructor decl (either the class name
or the 'constexpr' keyword).

Tested powerpc64le-linux, committed to trunk. Will backport to gcc-8
too.
commit b49a999a658a2073944c462be7b13a16bddb6daa
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri May 4 09:22:17 2018 +0100

    PR libstdc++/85642 fix is_nothrow_default_constructible<optional<T>>
    
    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.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index 0aa20dd9437..746ee2fd87e 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -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)
-      {}
+      : _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, 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>{}))
-      {}
+      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)
-      {}
+      : _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, 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>{}))
-      {}
+      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)
-      {}
+      : _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, 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>{}))
-      {}
+      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)
-      {}
+      : _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, 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>{}))
-      {}
+      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
index 00000000000..4d366f1d27c
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/85642.cc
@@ -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>);
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc b/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc
index ae55ab233f1..e9171ef7cc2 100644
--- a/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/value_neg.cc
@@ -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 }
   }
 }