diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-10 22:44:07 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-11-10 22:44:07 +0000 |
commit | 24c4f18d7028e31f9bf1e434c59b13f389d8e7e4 (patch) | |
tree | 82b7ad8a37e5fb0f27c2cddc50136d114462233b | |
parent | 1675d1be7ee8eed319ebb548803640231c920456 (diff) | |
download | gcc-24c4f18d7028e31f9bf1e434c59b13f389d8e7e4.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217322 138bc75d-0d04-0410-961f-82ee72b054a4
6 files changed, 60 insertions, 12 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 33aa6f03041..0f33b7aa5ad 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 d50d3c90991..c0052b39b04 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 8092ead6d41..b38f3ae45c3 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 4abdf4682be..a30029a0395 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 61bce4eb049..02eba79b9cf 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 a0ca00caf8a..8c1dd2e949f 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> |