diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2014-11-10 22:44:07 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2014-11-10 22:44:07 +0000 |
commit | 2abd4ee6b507ce4ed4cc1591e616e0abb0740cfb (patch) | |
tree | 82b7ad8a37e5fb0f27c2cddc50136d114462233b | |
parent | b12db70880b724e80346016579fd6bbddb2b1c2c (diff) | |
download | gcc-2abd4ee6b507ce4ed4cc1591e616e0abb0740cfb.zip gcc-2abd4ee6b507ce4ed4cc1591e616e0abb0740cfb.tar.gz gcc-2abd4ee6b507ce4ed4cc1591e616e0abb0740cfb.tar.bz2 |
Fix std::deque move construction with non-equal allocators.
* include/bits/stl_deque.h (_Deque_base::_Deque_base(_Deque_base&&)):
Dispatch according to whether allocators are always equal.
(_Deque_base::_M_move_impl()): Implement move-from state.
* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Fix
dg-error line number.
* testsuite/23_containers/deque/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/
constructor_2_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
Likewise.
From-SVN: r217322
6 files changed, 60 insertions, 12 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 33aa6f0..0f33b7a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2014-11-10 Jonathan Wakely <jwakely@redhat.com> + + * include/bits/stl_deque.h (_Deque_base::_Deque_base(_Deque_base&&)): + Dispatch according to whether allocators are always equal. + (_Deque_base::_M_move_impl()): Implement move-from state. + * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Fix + dg-error line number. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_2_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc: + Likewise. + 2014-11-10 François Dumont <fdumont@gcc.gnu.org> Major maintenance patch of the profile mode. diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index d50d3c90..c0052b3 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -502,14 +502,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { /* Caller must initialize map. */ } #if __cplusplus >= 201103L - _Deque_base(_Deque_base&& __x) - : _M_impl(__x._M_get_Tp_allocator()) + _Deque_base(_Deque_base&& __x, false_type) + : _M_impl(__x._M_move_impl()) + { } + + _Deque_base(_Deque_base&& __x, true_type) + : _M_impl(std::move(__x._M_get_Tp_allocator())) { _M_initialize_map(0); if (__x._M_impl._M_map) this->_M_impl._M_swap_data(__x._M_impl); } + _Deque_base(_Deque_base&& __x) + : _Deque_base(std::move(__x), + __gnu_cxx::__allocator_always_compares_equal<_Alloc>{}) + { } + _Deque_base(_Deque_base&& __x, const allocator_type& __a, size_type __n) : _M_impl(__a) { @@ -555,18 +564,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { } #if __cplusplus >= 201103L - _Deque_impl(_Tp_alloc_type&& __a) _GLIBCXX_NOEXCEPT + _Deque_impl(_Deque_impl&&) = default; + + _Deque_impl(_Tp_alloc_type&& __a) noexcept : _Tp_alloc_type(std::move(__a)), _M_map(), _M_map_size(0), _M_start(), _M_finish() { } #endif - void _M_swap_data(_Deque_impl& __x) + void _M_swap_data(_Deque_impl& __x) _GLIBCXX_NOEXCEPT { - std::swap(this->_M_start, __x._M_start); - std::swap(this->_M_finish, __x._M_finish); - std::swap(this->_M_map, __x._M_map); - std::swap(this->_M_map_size, __x._M_map_size); + using std::swap; + swap(this->_M_start, __x._M_start); + swap(this->_M_finish, __x._M_finish); + swap(this->_M_map, __x._M_map); + swap(this->_M_map_size, __x._M_map_size); } }; @@ -618,6 +630,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER enum { _S_initial_map_size = 8 }; _Deque_impl _M_impl; + +#if __cplusplus >= 201103L + private: + _Deque_impl + _M_move_impl() + { + if (!_M_impl._M_map) + return std::move(_M_impl); + + // Create a copy of the current allocator. + _Tp_alloc_type __alloc{_M_get_Tp_allocator()}; + // Put that copy in a moved-from state. + _Tp_alloc_type __unused __attribute((__unused__)) {std::move(__alloc)}; + // Create an empty map that allocates using the moved-from allocator. + _Deque_base __empty{__alloc}; + // Now safe to modify current allocator and perform non-throwing swaps. + _Deque_impl __ret{std::move(_M_get_Tp_allocator())}; + _M_impl._M_swap_data(__ret); + _M_impl._M_swap_data(__empty._M_impl); + return __ret; + } +#endif }; template<typename _Tp, typename _Alloc> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc index 8092ead..b38f3ae 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1859 } +// { dg-error "no matching" "" { target *-*-* } 1881 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc index 4abdf46..a30029a 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1792 } +// { dg-error "no matching" "" { target *-*-* } 1814 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc index 61bce4e..02eba79 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1792 } +// { dg-error "no matching" "" { target *-*-* } 1814 } #include <deque> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc index a0ca00c..8c1dd2e 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1943 } +// { dg-error "no matching" "" { target *-*-* } 1965 } #include <deque> |