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 <[email protected]>
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.
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});
+