From 3fe2ddae4b15a17184237097a5c9363eb94fe99a Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Mon, 3 Oct 2016 14:06:53 +0300 Subject: [PATCH] re PR libstdc++/77802 (Boost Fiber doesn't compile) PR libstdc++/77802 * testsuite/20_util/tuple/77802.cc: New. Revert: 2016-09-21 Ville Voutilainen Implement LWG 2729 for tuple. * include/std/tuple (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. (_Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&&)): Likewise. (__is_tuple_impl_trait_impl, __is_tuple_impl_trait): New. (_Tuple_impl(const _Head&)): Constrain. (_Tuple_impl(_UHead&&)): Likewise. (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. (_Tuple_impl(const _Tuple_impl<_Idx, _UHead>&)): Constrain. (_Tuple_impl(_Tuple_impl<_Idx, _UHead>&&)): Likewise. (operator=(const tuple&)): Enable conditionally. (operator=(tuple&&)): Suppress conditionally. (operator=(const tuple<_UElements...>&)): Constrain. (operator=(tuple<_UElements...>&&)): Likewise. (operator=(const tuple&)): Enable conditionally (2-param tuple). (operator=(tuple&&)): Suppress conditionally (2-param tuple). (operator=(const tuple<_U1, _U2>&)): Constrain. (operator=(tuple<_U1, _U2>&&)): Likewise. (operator=(const pair<_U1, _U2>&)): Likewise. (operator=(pair<_U1, _U2>&&)): Likewise. * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust. * testsuite/20_util/tuple/tuple_traits.cc: New. From-SVN: r240709 --- libstdc++-v3/ChangeLog | 30 +++ libstdc++-v3/include/std/tuple | 96 ++----- libstdc++-v3/testsuite/20_util/tuple/77802.cc | 49 ++++ .../20_util/tuple/element_access/get_neg.cc | 2 +- .../testsuite/20_util/tuple/tuple_traits.cc | 244 ------------------ 5 files changed, 97 insertions(+), 324 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/tuple/77802.cc delete mode 100644 libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index be41539547d..31dfa65bf56 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,33 @@ +2016-10-03 Ville Voutilainen + + PR libstdc++/77802 + * testsuite/20_util/tuple/77802.cc: New. + + Revert: + 2016-09-21 Ville Voutilainen + Implement LWG 2729 for tuple. + * include/std/tuple (_Tuple_impl(_Tuple_impl&&)): + Suppress conditionally. + (_Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&&)): Likewise. + (__is_tuple_impl_trait_impl, __is_tuple_impl_trait): New. + (_Tuple_impl(const _Head&)): Constrain. + (_Tuple_impl(_UHead&&)): Likewise. + (_Tuple_impl(_Tuple_impl&&)): Suppress conditionally. + (_Tuple_impl(const _Tuple_impl<_Idx, _UHead>&)): Constrain. + (_Tuple_impl(_Tuple_impl<_Idx, _UHead>&&)): Likewise. + (operator=(const tuple&)): Enable conditionally. + (operator=(tuple&&)): Suppress conditionally. + (operator=(const tuple<_UElements...>&)): Constrain. + (operator=(tuple<_UElements...>&&)): Likewise. + (operator=(const tuple&)): Enable conditionally (2-param tuple). + (operator=(tuple&&)): Suppress conditionally (2-param tuple). + (operator=(const tuple<_U1, _U2>&)): Constrain. + (operator=(tuple<_U1, _U2>&&)): Likewise. + (operator=(const pair<_U1, _U2>&)): Likewise. + (operator=(pair<_U1, _U2>&&)): Likewise. + * testsuite/20_util/tuple/element_access/get_neg.cc: Adjust. + * testsuite/20_util/tuple/tuple_traits.cc: New. + 2016-09-30 Jonathan Wakely PR libstdc++/77795 diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 32b932f79fd..c06a040a960 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -220,11 +220,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr - _Tuple_impl(typename conditional< - __and_, - is_move_constructible<_Inherited>>::value, - _Tuple_impl&&, __nonesuch&&>::type __in) - noexcept(__and_, + _Tuple_impl(_Tuple_impl&& __in) + noexcept(__and_, is_nothrow_move_constructible<_Inherited>>::value) : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } @@ -235,11 +232,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } template - constexpr _Tuple_impl(typename conditional< - __and_, - is_move_constructible<_Inherited>>::value, - _Tuple_impl<_Idx, _UHead, _UTails...>&&, - __nonesuch&&>::type __in) + constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) : _Inherited(std::move (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), _Base(std::forward<_UHead> @@ -345,18 +338,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; - template - struct __is_tuple_impl_trait_impl : false_type - { }; - - template - struct __is_tuple_impl_trait_impl<_Tuple_impl<_Idx, _Tp...>> : true_type - { }; - - template - struct __is_tuple_impl_trait : public __is_tuple_impl_trait_impl<_Tp> - { }; - // Basis case of inheritance recursion. template struct _Tuple_impl<_Idx, _Head> @@ -375,20 +356,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl() : _Base() { } - template::value, - bool>::type=true> explicit constexpr _Tuple_impl(const _Head& __head) : _Base(__head) { } - template, - __not_<__is_tuple_impl_trait< - typename - remove_reference<_UHead>::type>> - >::value, - bool>::type = true> + template explicit constexpr _Tuple_impl(_UHead&& __head) : _Base(std::forward<_UHead>(__head)) { } @@ -396,21 +368,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl(const _Tuple_impl&) = default; constexpr - _Tuple_impl(typename conditional< - is_move_constructible<_Head>::value, - _Tuple_impl&&, __nonesuch&&>::type __in) + _Tuple_impl(_Tuple_impl&& __in) noexcept(is_nothrow_move_constructible<_Head>::value) : _Base(std::forward<_Head>(_M_head(__in))) { } - template::value, - bool>::type = true> + template constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } - template::value, - bool>::type = true> + template constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) { } @@ -866,18 +832,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } tuple& - operator=(typename - conditional<__and_...>::value, - const tuple&, const __nonesuch&>::type __in) + operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& - operator=(typename - conditional<__and_...>::value, - tuple&&, __nonesuch&&>::type __in) + operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); @@ -886,10 +848,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template...>::value>::type> + == sizeof...(_Elements)>::type> tuple& operator=(const tuple<_UElements...>& __in) { @@ -899,10 +858,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template...>::value>::type> + == sizeof...(_Elements)>::type> tuple& operator=(tuple<_UElements...>&& __in) { @@ -1233,20 +1189,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::forward<_U2>(__in.second)) { } tuple& - operator=(typename - conditional<__and_, - is_copy_assignable<_T2>>::value, - const tuple&, const __nonesuch&>::type __in) + operator=(const tuple& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } tuple& - operator=(typename - conditional<__and_, - is_move_assignable<_T2>>::value, - tuple&&, __nonesuch&&>::type __in) + operator=(tuple&& __in) noexcept(is_nothrow_move_assignable<_Inherited>::value) { static_cast<_Inherited&>(*this) = std::move(__in); @@ -1254,10 +1204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - typename - enable_if<__and_, - is_assignable<_T2&, const _U2&>>::value, - tuple&>::type + tuple& operator=(const tuple<_U1, _U2>& __in) { static_cast<_Inherited&>(*this) = __in; @@ -1265,10 +1212,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - typename - enable_if<__and_, - is_assignable<_T2&, _U2&&>>::value, - tuple&>::type + tuple& operator=(tuple<_U1, _U2>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); @@ -1276,10 +1220,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - typename - enable_if<__and_, - is_assignable<_T2&, const _U2&>>::value, - tuple&>::type + tuple& operator=(const pair<_U1, _U2>& __in) { this->_M_head(*this) = __in.first; @@ -1288,10 +1229,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - typename - enable_if<__and_, - is_assignable<_T2&, _U2&&>>::value, - tuple&>::type + tuple& operator=(pair<_U1, _U2>&& __in) { this->_M_head(*this) = std::forward<_U1>(__in.first); diff --git a/libstdc++-v3/testsuite/20_util/tuple/77802.cc b/libstdc++-v3/testsuite/20_util/tuple/77802.cc new file mode 100644 index 00000000000..8a520106746 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/77802.cc @@ -0,0 +1,49 @@ +// { dg-do compile { target c++11 } } + +// Copyright (C) 2016 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 +// . + +#include + +// This testcase instantiates a tuple with an incomplete type. +// That is undefined behavior, but our tuple implementation manages +// to cope with this particular case. The attempt to provide +// a tuple implementation that yields the right result for +// traits like is_copy_constructible and is_move_constructible as +// per LWG 2729 results in ill-formed copy/move constructors being +// generated for a tuple that contains an incomplete type. +// Once we get concepts, we can solve that problem much easier. + +template struct execution_context +{ + typedef std::tuple args_tpl_t; + typedef std::tuple::type...> + ret_tpl_t; + execution_context(); + execution_context(execution_context &&); + ret_tpl_t operator()() { + args_tpl_t data; + return tuple_cat(std::forward_as_tuple(execution_context()), data); + } +}; + +void fn1() +{ + execution_context cc; + cc(); +} + diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc index 1c08d459648..5bcf5761c36 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc @@ -17,7 +17,7 @@ // { dg-options "-fno-show-column" } // { dg-do compile { target c++14 } } -// { dg-error "in range" "" { target *-*-* } 1342 } +// { dg-error "in range" "" { target *-*-* } 1280 } #include diff --git a/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc b/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc deleted file mode 100644 index b72f535a6fc..00000000000 --- a/libstdc++-v3/testsuite/20_util/tuple/tuple_traits.cc +++ /dev/null @@ -1,244 +0,0 @@ -// { dg-do compile { target c++11 } } - -// Copyright (C) 2016 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 -// . - -#include -#include -#include -#include -#include - -using namespace std; - -struct Poison -{ - Poison(Poison&&) = delete; -}; - - -int main() -{ - static_assert(!is_copy_constructible::value, ""); - static_assert(!is_move_constructible::value, ""); - static_assert(!is_copy_assignable::value, ""); - static_assert(!is_move_assignable::value, ""); - - static_assert(!is_copy_constructible>::value, ""); - static_assert(!is_move_constructible>::value, ""); - static_assert(!is_copy_assignable>::value, ""); - static_assert(!is_move_assignable>::value, ""); - - static_assert(!is_copy_constructible>::value, - ""); - static_assert(!is_move_constructible>::value, - ""); - static_assert(!is_copy_assignable>::value, ""); - static_assert(!is_move_assignable>::value, ""); - static_assert(!is_constructible&, - std::tuple&>::value, ""); - static_assert(!is_assignable&, - std::tuple&>::value, ""); - static_assert(!is_constructible&, - std::tuple>::value, ""); - static_assert(!is_assignable&, - std::tuple>::value, ""); - static_assert(!is_constructible&, - std::pair&>::value, ""); - static_assert(!is_assignable&, - std::pair&>::value, ""); - static_assert(!is_constructible&, - std::pair>::value, ""); - static_assert(!is_assignable&, - std::pair>::value, ""); - - static_assert(!is_copy_constructible< - std::tuple>::value, ""); - static_assert(!is_move_constructible< - std::tuple>::value, ""); - static_assert(!is_copy_assignable< - std::tuple>::value, ""); - static_assert(!is_move_assignable< - std::tuple>::value, ""); - static_assert(!is_constructible< - std::tuple&, - std::tuple&>::value, ""); - static_assert(!is_assignable< - std::tuple&, - std::tuple&>::value, ""); - static_assert(!is_constructible< - std::tuple&, - std::tuple>::value, ""); - static_assert(!is_assignable< - std::tuple&, - std::tuple>::value, ""); - static_assert(!is_constructible< - std::tuple&, - std::pair&>::value, ""); - static_assert(!is_assignable< - std::tuple&, - std::pair&>::value, ""); - static_assert(!is_constructible< - std::tuple&, - std::pair>::value, ""); - static_assert(!is_assignable< - std::tuple&, - std::pair>::value, ""); - - static_assert(is_trivially_copy_constructible>::value, ""); - static_assert(!is_trivially_move_constructible>::value, ""); - - static_assert(!is_trivially_copy_assignable>::value, ""); - static_assert(!is_trivially_move_assignable>::value, ""); - - static_assert(is_copy_constructible>::value, ""); - static_assert(is_move_constructible>::value, ""); - - static_assert(is_copy_assignable>::value, ""); - static_assert(is_move_assignable>::value, ""); - - static_assert(!is_trivially_copy_constructible< - tuple>>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>>::value, ""); - - static_assert(is_copy_constructible>>::value, ""); - static_assert(is_move_constructible>>::value, ""); - - static_assert(is_copy_assignable>>::value, ""); - static_assert(is_move_assignable>>::value, ""); - - static_assert(!is_trivially_copy_constructible< - tuple>>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>>::value, ""); - static_assert(!is_copy_constructible< - tuple>>::value, ""); - static_assert(is_move_constructible>>::value, ""); - - static_assert(!is_copy_assignable>>::value, ""); - static_assert(is_move_assignable>>::value, ""); - - static_assert(is_trivially_copy_constructible< - tuple>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>::value, ""); - - static_assert(is_copy_constructible>::value, ""); - static_assert(is_move_constructible>::value, ""); - - static_assert(is_copy_assignable>::value, ""); - static_assert(is_move_assignable>::value, ""); - static_assert(!is_trivially_copy_constructible< - tuple>>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>>::value, ""); - - static_assert(is_copy_constructible< - tuple>>::value, ""); - static_assert(is_move_constructible< - tuple>>::value, ""); - - static_assert(is_copy_assignable>>::value, ""); - static_assert(is_move_assignable>>::value, ""); - - static_assert(!is_trivially_copy_constructible< - tuple>>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>>::value, ""); - - static_assert(!is_copy_constructible< - tuple>>::value, ""); - static_assert(is_move_constructible< - tuple>>::value, ""); - - static_assert(!is_copy_assignable< - tuple>>::value, ""); - static_assert(is_move_assignable< - tuple>>::value, ""); - - static_assert(is_copy_constructible>::value, ""); - static_assert(is_move_constructible>::value, ""); - - static_assert(is_copy_assignable>::value, ""); - static_assert(is_move_assignable>::value, ""); - - static_assert(!is_trivially_copy_constructible< - tuple>>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>>::value, ""); - - static_assert(is_copy_constructible< - tuple>>::value, ""); - static_assert(is_move_constructible< - tuple>>::value, ""); - - static_assert(is_copy_assignable< - tuple>>::value, ""); - static_assert(is_move_assignable< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_constructible< - tuple>>::value, ""); - static_assert(!is_trivially_move_constructible< - tuple>>::value, ""); - - static_assert(!is_trivially_copy_assignable< - tuple>>::value, ""); - static_assert(!is_trivially_move_assignable< - tuple>>::value, ""); - - static_assert(!is_copy_constructible< - tuple>>::value, ""); - static_assert(is_move_constructible< - tuple>>::value, ""); - - static_assert(!is_copy_assignable< - tuple>>::value, ""); - static_assert(is_move_assignable< - tuple>>::value, ""); -} -- 2.30.2