public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/gccgo] libstdc++: Fix constructor constraints for std::any (PR 90415)
@ 2020-07-12 17:31 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2020-07-12 17:31 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:d1462b0782555354b4480e1f46498586d5882972
commit d1462b0782555354b4480e1f46498586d5882972
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Apr 24 00:54:20 2020 +0100
libstdc++: Fix constructor constraints for std::any (PR 90415)
This removes a non-standard extension to std::any which causes errors
for valid code, due to recursive instantiation of a trait that isn't
supposed to be in the constraints.
It also removes some incorrect constraints on the in_place_type<T>
constructors and emplace members, which were preventing creating a
std::any object with another std::any as the contained value.
2020-04-24 Kamlesh Kumar <kamleshbhalui@gmail.com>
Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/90415
PR libstdc++/92156
* include/std/any (any): Rename template parameters for consistency
with the standard.
(any::_Decay): Rename to _Decay_if_not_any.
(any::any(T&&):: Remove is_constructible from constraints. Remove
non-standard overload.
(any::any(in_place_type_t<T>, Args&&...))
(any::any(in_place_type_t<T>, initializer_list<U>, Args&&...))
(any::emplace(Args&&...))
(any::emplace(initializer_list<U>, Args&&...)):
Use decay_t instead of _Decay.
* testsuite/20_util/any/cons/90415.cc: New test.
* testsuite/20_util/any/cons/92156.cc: New Test.
* testsuite/20_util/any/misc/any_cast_neg.cc: Make dg-error directives
more robust.
* testsuite/20_util/any/modifiers/92156.cc: New test.
Diff:
---
libstdc++-v3/ChangeLog | 21 ++++
libstdc++-v3/include/std/any | 115 +++++++++------------
libstdc++-v3/testsuite/20_util/any/cons/90415.cc | 64 ++++++++++++
libstdc++-v3/testsuite/20_util/any/cons/92156.cc | 53 ++++++++++
.../testsuite/20_util/any/misc/any_cast_neg.cc | 16 +--
.../testsuite/20_util/any/modifiers/92156.cc | 57 ++++++++++
6 files changed, 255 insertions(+), 71 deletions(-)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ecb8617d02a..7b92ba7eebf 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,24 @@
+2020-04-24 Kamlesh Kumar <kamleshbhalui@gmail.com>
+ Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/90415
+ PR libstdc++/92156
+ * include/std/any (any): Rename template parameters for consistency
+ with the standard.
+ (any::_Decay): Rename to _Decay_if_not_any.
+ (any::any(T&&):: Remove is_constructible from constraints. Remove
+ non-standard overload.
+ (any::any(in_place_type_t<T>, Args&&...))
+ (any::any(in_place_type_t<T>, initializer_list<U>, Args&&...))
+ (any::emplace(Args&&...))
+ (any::emplace(initializer_list<U>, Args&&...)):
+ Use decay_t instead of _Decay.
+ * testsuite/20_util/any/cons/90415.cc: New test.
+ * testsuite/20_util/any/cons/92156.cc: New Test.
+ * testsuite/20_util/any/misc/any_cast_neg.cc: Make dg-error directives
+ more robust.
+ * testsuite/20_util/any/modifiers/92156.cc: New test.
+
2020-04-23 Jonathan Wakely <jwakely@redhat.com>
* doc/xml/manual/status_cxx2020.xml: Update C++20 status table.
diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any
index 6b7e68f0e63..e13292296d3 100644
--- a/libstdc++-v3/include/std/any
+++ b/libstdc++-v3/include/std/any
@@ -105,8 +105,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Manager_internal<_Tp>,
_Manager_external<_Tp>>;
- template<typename _Tp, typename _Decayed = decay_t<_Tp>>
- using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>;
+ template<typename _Tp, typename _VTp = decay_t<_Tp>>
+ using _Decay_if_not_any = enable_if_t<!is_same_v<_VTp, any>, _VTp>;
/// Emplace with an object created from @p __args as the contained object.
template <typename _Tp, typename... _Args,
@@ -125,10 +125,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void __do_emplace(initializer_list<_Up> __il, _Args&&... __args)
{
reset();
- _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
+ _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
_M_manager = &_Mgr::_S_manage;
}
+ template <typename _Res, typename _Tp, typename... _Args>
+ using __any_constructible
+ = enable_if<__and_<is_copy_constructible<_Tp>,
+ is_constructible<_Tp, _Args...>>::value,
+ _Res>;
+
+ template <typename _Tp, typename... _Args>
+ using __any_constructible_t
+ = typename __any_constructible<bool, _Tp, _Args...>::type;
+
+ template<typename _VTp, typename... _Args>
+ using __emplace_t
+ = typename __any_constructible<_VTp&, _VTp, _Args...>::type;
+
public:
// construct/destruct
@@ -165,65 +179,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
- template <typename _Res, typename _Tp, typename... _Args>
- using __any_constructible =
- enable_if<__and_<is_copy_constructible<_Tp>,
- is_constructible<_Tp, _Args...>>::value,
- _Res>;
-
- template <typename _Tp, typename... _Args>
- using __any_constructible_t =
- typename __any_constructible<bool, _Tp, _Args...>::type;
-
/// Construct with a copy of @p __value as the contained object.
- template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
- typename _Mgr = _Manager<_Tp>,
- __any_constructible_t<_Tp, _ValueType&&> = true,
- enable_if_t<!__is_in_place_type<_Tp>::value, bool> = true>
- any(_ValueType&& __value)
+ template <typename _Tp, typename _VTp = _Decay_if_not_any<_Tp>,
+ typename _Mgr = _Manager<_VTp>,
+ enable_if_t<is_copy_constructible<_VTp>::value
+ && !__is_in_place_type<_VTp>::value, bool> = true>
+ any(_Tp&& __value)
: _M_manager(&_Mgr::_S_manage)
{
- _Mgr::_S_create(_M_storage, std::forward<_ValueType>(__value));
- }
-
- /// Construct with a copy of @p __value as the contained object.
- template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
- typename _Mgr = _Manager<_Tp>,
- enable_if_t<__and_v<is_copy_constructible<_Tp>,
- __not_<is_constructible<_Tp, _ValueType&&>>,
- __not_<__is_in_place_type<_Tp>>>,
- bool> = false>
- any(_ValueType&& __value)
- : _M_manager(&_Mgr::_S_manage)
- {
- _Mgr::_S_create(_M_storage, __value);
+ _Mgr::_S_create(_M_storage, std::forward<_Tp>(__value));
}
/// Construct with an object created from @p __args as the contained object.
- template <typename _ValueType, typename... _Args,
- typename _Tp = _Decay<_ValueType>,
- typename _Mgr = _Manager<_Tp>,
- __any_constructible_t<_Tp, _Args&&...> = false>
+ template <typename _Tp, typename... _Args, typename _VTp = decay_t<_Tp>,
+ typename _Mgr = _Manager<_VTp>,
+ __any_constructible_t<_VTp, _Args&&...> = false>
explicit
- any(in_place_type_t<_ValueType>, _Args&&... __args)
+ any(in_place_type_t<_Tp>, _Args&&... __args)
: _M_manager(&_Mgr::_S_manage)
{
- _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
+ _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
}
/// Construct with an object created from @p __il and @p __args as
/// the contained object.
- template <typename _ValueType, typename _Up, typename... _Args,
- typename _Tp = _Decay<_ValueType>,
- typename _Mgr = _Manager<_Tp>,
- __any_constructible_t<_Tp, initializer_list<_Up>,
+ template <typename _Tp, typename _Up, typename... _Args,
+ typename _VTp = decay_t<_Tp>, typename _Mgr = _Manager<_VTp>,
+ __any_constructible_t<_VTp, initializer_list<_Up>,
_Args&&...> = false>
explicit
- any(in_place_type_t<_ValueType>,
- initializer_list<_Up> __il, _Args&&... __args)
+ any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args)
: _M_manager(&_Mgr::_S_manage)
{
- _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
+ _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
}
/// Destructor, calls @c reset()
@@ -232,7 +220,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// assignments
/// Copy the state of another object.
- any& operator=(const any& __rhs)
+ any&
+ operator=(const any& __rhs)
{
*this = any(__rhs);
return *this;
@@ -243,7 +232,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* @post @c !__rhs.has_value() (not guaranteed for other implementations)
*/
- any& operator=(any&& __rhs) noexcept
+ any&
+ operator=(any&& __rhs) noexcept
{
if (!__rhs.has_value())
reset();
@@ -258,40 +248,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/// Store a copy of @p __rhs as the contained object.
- template<typename _ValueType>
- enable_if_t<is_copy_constructible<_Decay<_ValueType>>::value, any&>
- operator=(_ValueType&& __rhs)
+ template<typename _Tp>
+ enable_if_t<is_copy_constructible<_Decay_if_not_any<_Tp>>::value, any&>
+ operator=(_Tp&& __rhs)
{
- *this = any(std::forward<_ValueType>(__rhs));
+ *this = any(std::forward<_Tp>(__rhs));
return *this;
}
/// Emplace with an object created from @p __args as the contained object.
- template <typename _ValueType, typename... _Args>
- typename __any_constructible<_Decay<_ValueType>&,
- _Decay<_ValueType>, _Args&&...>::type
+ template <typename _Tp, typename... _Args>
+ __emplace_t<decay_t<_Tp>, _Args...>
emplace(_Args&&... __args)
{
- __do_emplace<_Decay<_ValueType>>(std::forward<_Args>(__args)...);
+ using _VTp = decay_t<_Tp>;
+ __do_emplace<_VTp>(std::forward<_Args>(__args)...);
any::_Arg __arg;
this->_M_manager(any::_Op_access, this, &__arg);
- return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
+ return *static_cast<_VTp*>(__arg._M_obj);
}
/// Emplace with an object created from @p __il and @p __args as
/// the contained object.
- template <typename _ValueType, typename _Up, typename... _Args>
- typename __any_constructible<_Decay<_ValueType>&,
- _Decay<_ValueType>,
- initializer_list<_Up>,
- _Args&&...>::type
+ template <typename _Tp, typename _Up, typename... _Args>
+ __emplace_t<decay_t<_Tp>, initializer_list<_Up>, _Args&&...>
emplace(initializer_list<_Up> __il, _Args&&... __args)
{
- __do_emplace<_Decay<_ValueType>, _Up>(__il,
- std::forward<_Args>(__args)...);
+ using _VTp = decay_t<_Tp>;
+ __do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...);
any::_Arg __arg;
this->_M_manager(any::_Op_access, this, &__arg);
- return *static_cast<_Decay<_ValueType>*>(__arg._M_obj);
+ return *static_cast<_VTp*>(__arg._M_obj);
}
// modifiers
diff --git a/libstdc++-v3/testsuite/20_util/any/cons/90415.cc b/libstdc++-v3/testsuite/20_util/any/cons/90415.cc
new file mode 100644
index 00000000000..122262386d3
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/any/cons/90415.cc
@@ -0,0 +1,64 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// Copyright (C) 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/>.
+
+#include <any>
+#include <utility>
+#include <tuple>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ // PR libstdc++/90415
+ static_assert( std::is_copy_constructible<std::tuple<std::any>>::value );
+}
+
+struct wrapper
+{
+ wrapper() = default;
+
+ wrapper(const std::any& t);
+
+ wrapper(const wrapper& w);
+
+ auto& operator=(const std::any& t);
+
+ auto& operator=(const wrapper& w)
+ {
+ value = w.value;
+ return *this;
+ }
+
+ std::any value;
+};
+
+void
+test02()
+{
+ // PR libstdc++/91630
+ wrapper a, b;
+ a = b;
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/20_util/any/cons/92156.cc b/libstdc++-v3/testsuite/20_util/any/cons/92156.cc
new file mode 100644
index 00000000000..d797473716d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/any/cons/92156.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// Copyright (C) 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/>.
+
+#include <any>
+#include <utility>
+#include <tuple>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ auto a = std::any(std::in_place_type<std::any>, 5);
+ VERIFY( std::any_cast<int>(std::any_cast<std::any>(a)) == 5 );
+
+ auto b = std::any(std::in_place_type<std::any>, {1});
+ (void) std::any_cast<std::initializer_list<int>>(std::any_cast<std::any>(b));
+}
+
+void
+test02()
+{
+ std::any p = std::pair<std::any, std::any>(1, 1);
+ auto pt = std::any_cast<std::pair<std::any, std::any>>(p);
+ VERIFY( std::any_cast<int>(pt.first) == 1 );
+ VERIFY( std::any_cast<int>(pt.second) == 1 );
+
+ std::any t = std::tuple<std::any>(1);
+ auto tt = std::any_cast<std::tuple<std::any>>(t);
+ VERIFY( std::any_cast<int>(std::get<0>(tt)) == 1 );
+}
+
+int main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
index 6a271e8faab..049815a0c1f 100644
--- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc
@@ -1,5 +1,5 @@
// { dg-options "-std=gnu++17" }
-// { dg-do compile }
+// { dg-do compile { target c++17 } }
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
@@ -26,20 +26,22 @@ using std::any_cast;
void test01()
{
const any y(1);
- any_cast<int&>(y); // { dg-error "invalid 'static_cast'" "" { target { *-*-* } } 461 }
- // { dg-error "Template argument must be constructible from a const value" "" { target { *-*-* } } 457 }
+ any_cast<int&>(y); // { dg-error "here" }
+ // { dg-error "Template argument must be constructible from a const value" "" { target { *-*-* } } 0 }
}
void test02()
{
any y(1);
- any_cast<int&&>(y);
- // { dg-error "Template argument must be constructible from an lvalue" "" { target { *-*-* } } 483 }
+ any_cast<int&&>(y); // { dg-error "here" }
+ // { dg-error "Template argument must be constructible from an lvalue" "" { target { *-*-* } } 0 }
}
void test03()
{
any y(1);
- any_cast<int&>(std::move(y)); // { dg-error "invalid 'static_cast'" "" { target { *-*-* } } 501 }
- // { dg-error "Template argument must be constructible from an rvalue" "" { target { *-*-* } } 497 }
+ any_cast<int&>(std::move(y)); // { dg-error "here" }
+ // { dg-error "Template argument must be constructible from an rvalue" "" { target { *-*-* } } 0 }
}
+
+// { dg-prune-output "invalid 'static_cast'" }
diff --git a/libstdc++-v3/testsuite/20_util/any/modifiers/92156.cc b/libstdc++-v3/testsuite/20_util/any/modifiers/92156.cc
new file mode 100644
index 00000000000..4a7bc97bb83
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/any/modifiers/92156.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do run { target c++17 } }
+
+// Copyright (C) 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/>.
+
+#include <any>
+#include <utility>
+#include <tuple>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::any a;
+ a.emplace<std::any>(5);
+ VERIFY( std::any_cast<int>(std::any_cast<std::any>(a)) == 5 );
+
+ std::any b;
+ b.emplace<std::any>({1});
+ (void) std::any_cast<std::initializer_list<int>>(std::any_cast<std::any>(b));
+}
+
+void
+test02()
+{
+ std::any p;
+ p.emplace<std::pair<std::any, std::any>>(1, 1);
+ auto pt = std::any_cast<std::pair<std::any, std::any>>(p);
+ VERIFY( std::any_cast<int>(pt.first) == 1 );
+ VERIFY( std::any_cast<int>(pt.second) == 1 );
+
+ std::any t;
+ t.emplace<std::tuple<std::any>>(1);
+ auto tt = std::any_cast<std::tuple<std::any>>(t);
+ VERIFY( std::any_cast<int>(std::get<0>(tt)) == 1 );
+}
+
+int main()
+{
+ test01();
+ test02();
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-07-12 17:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-12 17:31 [gcc/devel/gccgo] libstdc++: Fix constructor constraints for std::any (PR 90415) Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).