diff mbox series

libstdc++: Fix tuple and optional construction from {aggregate_member_value} (libstdc++/94890)

Message ID CAFk2RUYbkVVX13xQ-rdzDNoib3v=S+UWdmBLXjY00N=05OxHrA@mail.gmail.com
State New
Headers show
Series libstdc++: Fix tuple and optional construction from {aggregate_member_value} (libstdc++/94890) | expand

Commit Message

Ville Voutilainen May 1, 2020, 6:15 p.m. UTC
Aggregate-paren-init breaks tuple and optional. This fixes the breakage.
An LWG issue will be filed.

Full suite test run pending. Ok for master and gcc-10 if the full tests pass?

2020-05-01  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/94890
    * include/std/optional (optional(_Up&&)): Add is_aggregate
    to the convertibility constraints.
    * include/std/tuple (__is_implicitly_constructible)
    (__is_explicitly_constructible): Likewise.
    * testsuite/20_util/optional/cons/94890.cc: New.
    * testsuite/20_util/tuple/cons/94890.cc: Likewise.

Comments

Ville Voutilainen May 1, 2020, 10:54 p.m. UTC | #1
On Fri, 1 May 2020 at 21:15, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
>
> Aggregate-paren-init breaks tuple and optional. This fixes the breakage.
> An LWG issue will be filed.

The previous approach was bogus. Here's a better one. Ok for master
and gcc-10 if
full testsuite run passes?

2020-05-02  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR libstdc++/94890
    * include/std/optional (__no_cpp20_converting_aggregates): New.
    (optional(_Up&&)): Use it.
    * include/std/tuple (__no_cpp20_converting_aggregates): New.
    (__valid_args): Use it.
    * testsuite/20_util/optional/cons/94890.cc: New.
    * testsuite/20_util/tuple/cons/94890.cc: Likewise.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional
index 37c2ba7a025..e0e307bc5f5 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -696,7 +696,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up = _Tp,
 	       _Requires<__not_self<_Up>, __not_tag<_Up>,
 			 is_constructible<_Tp, _Up&&>,
+#if __cpp_aggregate_paren_init
+			 __or_<is_aggregate<_Tp>,
+			       is_convertible<_Up&&, _Tp>>> = true>
+#else
 			 is_convertible<_Up&&, _Tp>> = true>
+#endif      
 	constexpr
 	optional(_Up&& __t)
 	: _Base(std::in_place, std::forward<_Up>(__t)) { }
@@ -704,7 +709,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Up = _Tp,
 	       _Requires<__not_self<_Up>, __not_tag<_Up>,
 			 is_constructible<_Tp, _Up&&>,
+#if __cpp_aggregate_paren_init
+			 __not_<__or_<is_aggregate<_Tp>,
+				      is_convertible<_Up&&, _Tp>>>> = false>
+#else
 			 __not_<is_convertible<_Up&&, _Tp>>> = false>
+#endif
 	explicit constexpr
 	optional(_Up&& __t)
         : _Base(std::in_place, std::forward<_Up>(__t)) { }
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index db4872d3a52..7744d9c402d 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -467,7 +467,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	static constexpr bool __is_implicitly_constructible()
 	{
 	  return __and_<is_constructible<_Types, _UTypes>...,
+#if __cpp_aggregate_paren_init
+			__or_<is_aggregate<_Types>,
+			      is_convertible<_UTypes, _Types>>...
+#else
 			is_convertible<_UTypes, _Types>...
+#endif
 			>::value;
 	}
 
@@ -478,8 +483,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	static constexpr bool __is_explicitly_constructible()
 	{
 	  return __and_<is_constructible<_Types, _UTypes>...,
-			__not_<__and_<is_convertible<_UTypes, _Types>...>>
-			>::value;
+			__not_<__and_<
+#if __cpp_aggregate_paren_init
+			         __or_<is_aggregate<_Types>,
+				       is_convertible<_UTypes, _Types>>...>
+#else
+			         is_convertible<_UTypes, _Types>...>
+#endif
+			>>::value;
 	}
 
       static constexpr bool __is_implicitly_default_constructible()
diff --git a/libstdc++-v3/testsuite/20_util/optional/cons/94890.cc b/libstdc++-v3/testsuite/20_util/optional/cons/94890.cc
new file mode 100644
index 00000000000..f66ddb7db13
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/cons/94890.cc
@@ -0,0 +1,26 @@ 
+// Copyright (C) 2019-2020 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 c { int i; };
+
+std::optional<c> x({0});
+
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/94890.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/94890.cc
new file mode 100644
index 00000000000..76b99c9fd05
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/94890.cc
@@ -0,0 +1,25 @@ 
+// Copyright (C) 2019-2020 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-do compile { target c++11 } }
+
+#include <tuple>
+
+struct c { int i; };
+
+std::tuple<c> x({0});
+