From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1725) id 8C70D3840C3C; Tue, 18 Aug 2020 18:14:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8C70D3840C3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1597774452; bh=rbihlYbKaBOEJ3agGxFAWjifHzXk8xlqmnF8b6MbENI=; h=From:To:Subject:Date:From; b=nN0LxL7OMPy4rlANqq1kwI6dYito9egN31Nec8jHaklIZRDCMRyjvZzfelHl1MxeH YyYZcXg3/JP+HLa59Mm295CGGDc8fqZm8P6KJiAYUquHGWia1/2UmGB+E3C5xYySlG 5cDfNrRUO5KwZLe6cNzdAT/dBl5b6lmOogxlGnDg= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: William Schmidt To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/users/wschmidt/heads/builtins3)] libstdc++: Fix unordered containers move constructors noexcept qualification X-Act-Checkin: gcc X-Git-Author: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Git-Refname: refs/users/wschmidt/heads/builtins3 X-Git-Oldrev: f1660ceb0d3b0076555058087307f88b80619a6f X-Git-Newrev: 12324b9a934654a5c3bf4a614853ded2e0a958af Message-Id: <20200818181412.8C70D3840C3C@sourceware.org> Date: Tue, 18 Aug 2020 18:14:12 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Aug 2020 18:14:12 -0000 https://gcc.gnu.org/g:12324b9a934654a5c3bf4a614853ded2e0a958af commit 12324b9a934654a5c3bf4a614853ded2e0a958af Author: François Dumont Date: Mon Jan 20 19:15:43 2020 +0100 libstdc++: Fix unordered containers move constructors noexcept qualification _Hashtable move constructor is wrongly qualified as noexcept(true) regardless of _Equal and _H1 copy constructor qualifications. _Hashtable allocator-aware move constructor is missing its noexcept qualification like the depending unordered containers ones. libstdc++-v3/ChangeLog: * include/bits/hashtable.h (_Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a, true_type)): Add noexcept qualification. (_Hashtable(_Hashtable&&)): Fix noexcept qualification. (_Hashtable(_Hashtable&&, const allocator_type&)): Add noexcept qualification. * include/bits/unordered_map.h (unordered_map(unordered_map&&, const allocator_type&)): Add noexcept qualification. (unordered_multimap(unordered_multimap&&, const allocator_type&)): Likewise. * include/bits/unordered_set.h (unordered_set(unordered_set&&, const allocator_type&)): Likewise. (unordered_multiset(unordered_multiset&&, const allocator_type&)): Likewise. * include/debug/unordered_map (unordered_map(unordered_map&&, const allocator_type&)): Likewise. (unordered_multimap(unordered_multimap&&, const allocator_type&)): Likewise. * include/debug/unordered_set (unordered_set(unordered_set&&, const allocator_type&)): Likewise. (unordered_multiset(unordered_multiset&&, const allocator_type&)): Likewise. * testsuite/23_containers/unordered_map/allocator/default_init.cc: New test. * testsuite/23_containers/unordered_map/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc: New test. * testsuite/23_containers/unordered_map/modifiers/move_assign.cc: New test. * testsuite/23_containers/unordered_multimap/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc: New test. * testsuite/23_containers/unordered_multiset/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc: New test. * testsuite/23_containers/unordered_set/allocator/default_init.cc: New test. * testsuite/23_containers/unordered_set/cons/noexcept_default_construct.cc: New test. * testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc: New test. Diff: --- libstdc++-v3/include/bits/hashtable.h | 40 +++++++++-- libstdc++-v3/include/bits/unordered_map.h | 2 + libstdc++-v3/include/bits/unordered_set.h | 2 + libstdc++-v3/include/debug/unordered_map | 18 ++--- libstdc++-v3/include/debug/unordered_set | 26 +++---- .../unordered_map/allocator/default_init.cc | 69 ++++++++++++++++++ .../cons/noexcept_default_construct.cc | 68 ++++++++++++++++++ .../unordered_map/cons/noexcept_move_construct.cc | 65 +++++++++++++++++ .../unordered_map/modifiers/move_assign.cc | 81 ++++++++++++++++++++++ .../cons/noexcept_default_construct.cc | 68 ++++++++++++++++++ .../cons/noexcept_move_construct.cc | 65 +++++++++++++++++ .../cons/noexcept_default_construct.cc | 68 ++++++++++++++++++ .../cons/noexcept_move_construct.cc | 65 +++++++++++++++++ .../unordered_set/allocator/default_init.cc | 69 ++++++++++++++++++ .../cons/noexcept_default_construct.cc | 68 ++++++++++++++++++ .../unordered_set/cons/noexcept_move_construct.cc | 65 +++++++++++++++++ 16 files changed, 812 insertions(+), 27 deletions(-) diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index 9d1ad592553..dc8ed2ee18c 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -460,6 +460,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __hashtable_alloc(__node_alloc_type(__a)) { } + _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a, + true_type /* alloc always equal */) + noexcept(std::is_nothrow_copy_constructible<_H1>::value && + std::is_nothrow_copy_constructible<_Equal>::value); + + _Hashtable(_Hashtable&&, __node_alloc_type&&, + false_type /* alloc always equal */); + template _Hashtable(_InputIterator __first, _InputIterator __last, size_type __bkt_count_hint, @@ -486,11 +494,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Hashtable(const _Hashtable&); - _Hashtable(_Hashtable&&) noexcept; + _Hashtable(_Hashtable&& __ht) + noexcept( noexcept( + _Hashtable(std::declval<_Hashtable>(), + std::declval<__node_alloc_type>(), + true_type{})) ) + : _Hashtable(std::move(__ht), std::move(__ht._M_node_allocator()), + true_type{}) + { } _Hashtable(const _Hashtable&, const allocator_type&); - _Hashtable(_Hashtable&&, const allocator_type&); + _Hashtable(_Hashtable&& __ht, const allocator_type& __a) + noexcept( noexcept( + _Hashtable(std::declval<_Hashtable>(), + std::declval<__node_alloc_type>(), + typename __node_alloc_traits::is_always_equal{})) ) + : _Hashtable(std::move(__ht), __node_alloc_type(__a), + typename __node_alloc_traits::is_always_equal{}) + { } // Use delegating constructors. template @@ -1342,18 +1364,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: - _Hashtable(_Hashtable&& __ht) noexcept + _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a, + true_type /* alloc always equal */) + noexcept(std::is_nothrow_copy_constructible<_H1>::value && + std::is_nothrow_copy_constructible<_Equal>::value) : __hashtable_base(__ht), __map_base(__ht), __rehash_base(__ht), - __hashtable_alloc(std::move(__ht._M_base_alloc())), + __hashtable_alloc(std::move(__a)), _M_buckets(__ht._M_buckets), _M_bucket_count(__ht._M_bucket_count), _M_before_begin(__ht._M_before_begin._M_nxt), _M_element_count(__ht._M_element_count), _M_rehash_policy(__ht._M_rehash_policy) { - // Update, if necessary, buckets if __ht is using its single bucket. + // Update buckets if __ht is using its single bucket. if (__ht._M_uses_single_bucket()) { _M_buckets = &_M_single_bucket; @@ -1392,11 +1417,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Traits> _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: - _Hashtable(_Hashtable&& __ht, const allocator_type& __a) + _Hashtable(_Hashtable&& __ht, __node_alloc_type&& __a, + false_type /* alloc always equal */) : __hashtable_base(__ht), __map_base(__ht), __rehash_base(__ht), - __hashtable_alloc(__node_alloc_type(__a)), + __hashtable_alloc(std::move(__a)), _M_buckets(nullptr), _M_bucket_count(__ht._M_bucket_count), _M_element_count(__ht._M_element_count), diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 33f632ddb79..1aaa1a1a6ee 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -209,6 +209,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_map(unordered_map&& __umap, const allocator_type& __a) + noexcept( noexcept(_Hashtable(std::move(__umap._M_h), __a)) ) : _M_h(std::move(__umap._M_h), __a) { } @@ -1303,6 +1304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_multimap(unordered_multimap&& __ummap, const allocator_type& __a) + noexcept( noexcept(_Hashtable(std::move(__ummap._M_h), __a)) ) : _M_h(std::move(__ummap._M_h), __a) { } diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index c9c9e9f38b7..6cbfcb1f0b6 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -203,6 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_set(unordered_set&& __uset, const allocator_type& __a) + noexcept( noexcept(_Hashtable(std::move(__uset._M_h), __a)) ) : _M_h(std::move(__uset._M_h), __a) { } @@ -1044,6 +1045,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_multiset(unordered_multiset&& __umset, const allocator_type& __a) + noexcept( noexcept(_Hashtable(std::move(__umset._M_h), __a)) ) : _M_h(std::move(__umset._M_h), __a) { } diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 7d55174f63b..4fa5c124d5a 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -144,6 +144,7 @@ namespace __debug unordered_map(unordered_map&& __umap, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__umap._M_base()), __a)) ) : _Safe(std::move(__umap._M_safe()), __a), _Base(std::move(__umap._M_base()), __a) { } @@ -168,7 +169,7 @@ namespace __debug unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) + : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) { } template @@ -176,20 +177,20 @@ namespace __debug size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_map(__first, __last, __n, __hf, key_equal(), __a) + : unordered_map(__first, __last, __n, __hf, key_equal(), __a) { } unordered_map(initializer_list __l, size_type __n, const allocator_type& __a) - : unordered_map(__l, __n, hasher(), key_equal(), __a) + : unordered_map(__l, __n, hasher(), key_equal(), __a) { } unordered_map(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_map(__l, __n, __hf, key_equal(), __a) + : unordered_map(__l, __n, __hf, key_equal(), __a) { } ~unordered_map() = default; @@ -847,6 +848,7 @@ namespace __debug unordered_multimap(unordered_multimap&& __umap, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__umap._M_base()), __a)) ) : _Safe(std::move(__umap._M_safe()), __a), _Base(std::move(__umap._M_base()), __a) { } @@ -870,26 +872,26 @@ namespace __debug unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) + : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) + : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multimap(initializer_list __l, size_type __n, const allocator_type& __a) - : unordered_multimap(__l, __n, hasher(), key_equal(), __a) + : unordered_multimap(__l, __n, hasher(), key_equal(), __a) { } unordered_multimap(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multimap(__l, __n, __hf, key_equal(), __a) + : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } ~unordered_multimap() = default; diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index 37031da947e..94dde0d0ded 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -141,6 +141,7 @@ namespace __debug unordered_set(unordered_set&& __uset, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__uset._M_base()), __a)) ) : _Safe(std::move(__uset._M_safe()), __a), _Base(std::move(__uset._M_base()), __a) { } @@ -152,38 +153,38 @@ namespace __debug : _Base(__l, __n, __hf, __eql, __a) { } unordered_set(size_type __n, const allocator_type& __a) - : unordered_set(__n, hasher(), key_equal(), __a) + : unordered_set(__n, hasher(), key_equal(), __a) { } unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_set(__n, __hf, key_equal(), __a) + : unordered_set(__n, __hf, key_equal(), __a) { } template unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) + : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_set(__first, __last, __n, __hf, key_equal(), __a) + : unordered_set(__first, __last, __n, __hf, key_equal(), __a) { } unordered_set(initializer_list __l, size_type __n, const allocator_type& __a) - : unordered_set(__l, __n, hasher(), key_equal(), __a) + : unordered_set(__l, __n, hasher(), key_equal(), __a) { } unordered_set(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_set(__l, __n, __hf, key_equal(), __a) + : unordered_set(__l, __n, __hf, key_equal(), __a) { } ~unordered_set() = default; @@ -717,6 +718,7 @@ namespace __debug unordered_multiset(unordered_multiset&& __uset, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__uset._M_base()), __a)) ) : _Safe(std::move(__uset._M_safe()), __a), _Base(std::move(__uset._M_base()), __a) { } @@ -728,38 +730,38 @@ namespace __debug : _Base(__l, __n, __hf, __eql, __a) { } unordered_multiset(size_type __n, const allocator_type& __a) - : unordered_multiset(__n, hasher(), key_equal(), __a) + : unordered_multiset(__n, hasher(), key_equal(), __a) { } unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multiset(__n, __hf, key_equal(), __a) + : unordered_multiset(__n, __hf, key_equal(), __a) { } template unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) - : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) + : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) { } template unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) + : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) { } unordered_multiset(initializer_list __l, size_type __n, const allocator_type& __a) - : unordered_multiset(__l, __n, hasher(), key_equal(), __a) + : unordered_multiset(__l, __n, hasher(), key_equal(), __a) { } unordered_multiset(initializer_list __l, size_type __n, const hasher& __hf, const allocator_type& __a) - : unordered_multiset(__l, __n, __hf, key_equal(), __a) + : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } ~unordered_multiset() = default; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/default_init.cc new file mode 100644 index 00000000000..473a5f1ce47 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/default_init.cc @@ -0,0 +1,69 @@ +// 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 +// . + +// { dg-do run { target c++11 } } +// { dg-options "-O0" } +// { dg-xfail-run-if "PR c++/65816" { *-*-* } } + +#include +#include +#include + +#include + +using T = int; + +using __gnu_test::default_init_allocator; + +void test01() +{ + typedef default_init_allocator> alloc_type; + typedef std::unordered_map, std::equal_to, + alloc_type> test_type; + + __gnu_cxx::__aligned_buffer buf; + __builtin_memset(buf._M_addr(), ~0, sizeof(test_type)); + + test_type *tmp = ::new(buf._M_addr()) test_type; + + VERIFY( tmp->get_allocator().state == 0 ); + + tmp->~test_type(); +} + +void test02() +{ + typedef default_init_allocator> alloc_type; + typedef std::unordered_map, std::equal_to, + alloc_type> test_type; + + __gnu_cxx::__aligned_buffer buf; + __builtin_memset(buf._M_addr(), ~0, sizeof(test_type)); + + test_type *tmp = ::new(buf._M_addr()) test_type(); + + VERIFY( tmp->get_allocator().state == 0 ); + + tmp->~test_type(); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_default_construct.cc new file mode 100644 index 00000000000..f859ec939d0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_default_construct.cc @@ -0,0 +1,68 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + +using type1 = std::unordered_map; + +static_assert(std::is_nothrow_default_constructible::value, + "noexcept default constructible"); + +struct not_noexcept_dflt_cons_hash +{ + not_noexcept_dflt_cons_hash() /* noexcept */; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_map; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +struct not_noexcept_dflt_cons_equal_to +{ + not_noexcept_dflt_cons_equal_to() /* noexcept */; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_map, + not_noexcept_dflt_cons_equal_to>; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +template + struct not_noexcept_dflt_cons_alloc : std::allocator<_Tp> + { + not_noexcept_dflt_cons_alloc() /* noexcept */; + + template + struct rebind + { typedef not_noexcept_dflt_cons_alloc<_Tp1> other; }; + }; + +using type4 = std::unordered_map, std::equal_to, + not_noexcept_dflt_cons_alloc>>; + +static_assert(!std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..99852b248d0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/noexcept_move_construct.cc @@ -0,0 +1,65 @@ +// { dg-do compile { target c++11 } } + +// 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 +// . + +#include + +using type1 = std::unordered_map; + +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_hash +{ + not_noexcept_copy_cons_hash() noexcept; + not_noexcept_copy_cons_hash(const not_noexcept_copy_cons_hash&) /* noexcept */; + not_noexcept_copy_cons_hash(not_noexcept_copy_cons_hash&&) noexcept; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_map; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_equal_to +{ + not_noexcept_copy_cons_equal_to() noexcept; + not_noexcept_copy_cons_equal_to(const not_noexcept_copy_cons_equal_to&) /* noexcept */; + not_noexcept_copy_cons_equal_to(not_noexcept_copy_cons_equal_to&&) noexcept; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_map, + not_noexcept_copy_cons_equal_to>; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/move_assign.cc new file mode 100644 index 00000000000..0a5ef1113d9 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/modifiers/move_assign.cc @@ -0,0 +1,81 @@ +// { dg-do compile { target c++11 } } + +// 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 +// . + +#include +#include +#include + +#include +#include +#include + +void test01() +{ + using namespace std; + using __gnu_test::counter_type; + + std::vector> insts { { 0, 0 }, { 1, 1 }, { 2, 2 } }; + typedef unordered_map Map; + Map m; + + counter_type::reset(); + + m.insert(make_move_iterator(insts.begin()), make_move_iterator(insts.end())); + + VERIFY( m.size() == 3 ); + VERIFY( counter_type::default_count == 0 ); + VERIFY( counter_type::copy_count == 0 ); + VERIFY( counter_type::move_count == 3 ); +} + +void test02() +{ + using namespace std; + using __gnu_test::counter_type; + using __gnu_test::propagating_allocator; + + typedef propagating_allocator, false> Alloc; + typedef unordered_map, equal_to, + Alloc> Map; + + Alloc a1(1); + Map m1(3, a1); + m1 = { { 0, 0 }, { 1, 1 }, { 2, 2 } }; + Alloc a2(2); + Map m2(3, a2); + m2 = { { 3, 0 }, { 4, 1 }, { 5, 2 } }; + + counter_type::reset(); + + m2 = move(m1); + + VERIFY( m1.empty() ); + VERIFY( m2.size() == 3 ); + VERIFY( counter_type::default_count == 0 ); + VERIFY( counter_type::copy_count == 0 ); + VERIFY( counter_type::move_count == 3 ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_default_construct.cc new file mode 100644 index 00000000000..98e2b017ca9 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_default_construct.cc @@ -0,0 +1,68 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + +using type1 = std::unordered_multimap; + +static_assert(std::is_nothrow_default_constructible::value, + "noexcept default constructible"); + +struct not_noexcept_dflt_cons_hash +{ + not_noexcept_dflt_cons_hash() /* noexcept */; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_multimap; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +struct not_noexcept_dflt_cons_equal_to +{ + not_noexcept_dflt_cons_equal_to() /* noexcept */; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_multimap, + not_noexcept_dflt_cons_equal_to>; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +template + struct not_noexcept_dflt_cons_alloc : std::allocator<_Tp> + { + not_noexcept_dflt_cons_alloc() /* noexcept */; + + template + struct rebind + { typedef not_noexcept_dflt_cons_alloc<_Tp1> other; }; + }; + +using type4 = std::unordered_multimap, std::equal_to, + not_noexcept_dflt_cons_alloc>>; + +static_assert(!std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..1d60c0184eb --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/noexcept_move_construct.cc @@ -0,0 +1,65 @@ +// { dg-do compile { target c++11 } } + +// 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 +// . + +#include + +using type1 = std::unordered_multimap; + +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_hash +{ + not_noexcept_copy_cons_hash() noexcept; + not_noexcept_copy_cons_hash(const not_noexcept_copy_cons_hash&) /* noexcept */; + not_noexcept_copy_cons_hash(not_noexcept_copy_cons_hash&&) noexcept; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_multimap; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_equal_to +{ + not_noexcept_copy_cons_equal_to() noexcept; + not_noexcept_copy_cons_equal_to(const not_noexcept_copy_cons_equal_to&) /* noexcept */; + not_noexcept_copy_cons_equal_to(not_noexcept_copy_cons_equal_to&&) noexcept; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_multimap, + not_noexcept_copy_cons_equal_to>; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_default_construct.cc new file mode 100644 index 00000000000..b7c0d802125 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_default_construct.cc @@ -0,0 +1,68 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + +using type1 = std::unordered_multiset; + +static_assert(std::is_nothrow_default_constructible::value, + "noexcept default constructible"); + +struct not_noexcept_dflt_cons_hash +{ + not_noexcept_dflt_cons_hash() /* noexcept */; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_multiset; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +struct not_noexcept_dflt_cons_equal_to +{ + not_noexcept_dflt_cons_equal_to() /* noexcept */; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_multiset, + not_noexcept_dflt_cons_equal_to>; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +template + struct not_noexcept_dflt_cons_alloc : std::allocator<_Tp> + { + not_noexcept_dflt_cons_alloc() /* noexcept */; + + template + struct rebind + { typedef not_noexcept_dflt_cons_alloc<_Tp1> other; }; + }; + +using type4 = std::unordered_multiset, std::equal_to, + not_noexcept_dflt_cons_alloc>>; + +static_assert(!std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..dd0e4ca920b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/noexcept_move_construct.cc @@ -0,0 +1,65 @@ +// { dg-do compile { target c++11 } } + +// 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 +// . + +#include + +using type1 = std::unordered_multiset; + +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_hash +{ + not_noexcept_copy_cons_hash() noexcept; + not_noexcept_copy_cons_hash(const not_noexcept_copy_cons_hash&) /* noexcept */; + not_noexcept_copy_cons_hash(not_noexcept_copy_cons_hash&&) noexcept; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_multiset; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_equal_to +{ + not_noexcept_copy_cons_equal_to() noexcept; + not_noexcept_copy_cons_equal_to(const not_noexcept_copy_cons_equal_to&) /* noexcept */; + not_noexcept_copy_cons_equal_to(not_noexcept_copy_cons_equal_to&&) noexcept; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_multiset, + not_noexcept_copy_cons_equal_to>; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/default_init.cc new file mode 100644 index 00000000000..37110dd6eb0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/allocator/default_init.cc @@ -0,0 +1,69 @@ +// 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 +// . + +// { dg-do run { target c++11 } } +// { dg-options "-O0" } +// { dg-xfail-run-if "PR c++/65816" { *-*-* } } + +#include +#include +#include + +#include + +using T = int; + +using __gnu_test::default_init_allocator; + +void test01() +{ + typedef default_init_allocator alloc_type; + typedef std::unordered_set, std::equal_to, + alloc_type> test_type; + + __gnu_cxx::__aligned_buffer buf; + __builtin_memset(buf._M_addr(), ~0, sizeof(test_type)); + + test_type *tmp = ::new(buf._M_addr()) test_type; + + VERIFY( tmp->get_allocator().state == 0 ); + + tmp->~test_type(); +} + +void test02() +{ + typedef default_init_allocator alloc_type; + typedef std::unordered_set, std::equal_to, + alloc_type> test_type; + + __gnu_cxx::__aligned_buffer buf; + __builtin_memset(buf._M_addr(), ~0, sizeof(test_type)); + + test_type *tmp = ::new(buf._M_addr()) test_type(); + + VERIFY( tmp->get_allocator().state == 0 ); + + tmp->~test_type(); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_default_construct.cc new file mode 100644 index 00000000000..d60a81ffb7c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_default_construct.cc @@ -0,0 +1,68 @@ +// 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 +// . + +// { dg-do compile { target c++11 } } + +#include + +using type1 = std::unordered_set; + +static_assert(std::is_nothrow_default_constructible::value, + "noexcept default constructible"); + +struct not_noexcept_dflt_cons_hash +{ + not_noexcept_dflt_cons_hash() /* noexcept */; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_set; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +struct not_noexcept_dflt_cons_equal_to +{ + not_noexcept_dflt_cons_equal_to() /* noexcept */; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_set, + not_noexcept_dflt_cons_equal_to>; + +static_assert( !std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); + +template + struct not_noexcept_dflt_cons_alloc : std::allocator<_Tp> + { + not_noexcept_dflt_cons_alloc() /* noexcept */; + + template + struct rebind + { typedef not_noexcept_dflt_cons_alloc<_Tp1> other; }; + }; + +using type4 = std::unordered_set, std::equal_to, + not_noexcept_dflt_cons_alloc>>; + +static_assert(!std::is_nothrow_default_constructible::value, + "not noexcept default constructible"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc new file mode 100644 index 00000000000..9be5ed07a33 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/noexcept_move_construct.cc @@ -0,0 +1,65 @@ +// { dg-do compile { target c++11 } } + +// 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 +// . + +#include + +using type1 = std::unordered_set; + +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_hash +{ + not_noexcept_copy_cons_hash() noexcept; + not_noexcept_copy_cons_hash(const not_noexcept_copy_cons_hash&) /* noexcept */; + not_noexcept_copy_cons_hash(not_noexcept_copy_cons_hash&&) noexcept; + + std::size_t + operator()(int) const noexcept; +}; + +using type2 = std::unordered_set; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" ); + +struct not_noexcept_copy_cons_equal_to +{ + not_noexcept_copy_cons_equal_to() noexcept; + not_noexcept_copy_cons_equal_to(const not_noexcept_copy_cons_equal_to&) /* noexcept */; + not_noexcept_copy_cons_equal_to(not_noexcept_copy_cons_equal_to&&) noexcept; + + bool + operator()(int, int) const noexcept; +}; + +using type3 = std::unordered_set, + not_noexcept_copy_cons_equal_to>; + +static_assert( !std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( !std::is_nothrow_constructible::value, + "not noexcept move constructor with allocator" );