From 1217f2a0338e4d5a61411668037e62c4c0152185 Mon Sep 17 00:00:00 2001 From: fdumont Date: Tue, 29 Jul 2014 19:47:19 +0000 Subject: [PATCH] =?utf8?q?2014-07-29=20=20Fran=C3=A7ois=20Dumont=20=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * testsuite/util/testsuite_allocator.h (tracker_allocator_counter::allocate): Remove new invocation, only collect information. (tracker_allocator_counter::deallocate): Remove delete invocation, only collect information. (check_inconsistent_alloc_value_type): New. (tracker_allocator): Transform as a facade for any allocator type. (uneq_allocator): Likewise. (propagating_allocator): Likewise. * testsuite/23_containers/forward_list/debug/move_assign_neg.cc: Use an explicitly non propagating allocator. * testsuite/23_containers/map/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/multimap/debug/move_assign_neg.cc: likewise. * testsuite/23_containers/multiset/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/set/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/unordered_map/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/unordered_set/debug/move_assign_neg.cc: Likewise. * testsuite/23_containers/vector/debug/move_assign_neg.cc: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213224 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 27 ++ .../forward_list/debug/move_assign_neg.cc | 2 +- .../23_containers/map/debug/move_assign_neg.cc | 3 +- .../multimap/debug/move_assign_neg.cc | 3 +- .../multiset/debug/move_assign_neg.cc | 2 +- .../23_containers/set/debug/move_assign_neg.cc | 2 +- .../unordered_map/debug/move_assign_neg.cc | 3 +- .../unordered_multimap/debug/move_assign_neg.cc | 3 +- .../unordered_multiset/debug/move_assign_neg.cc | 2 +- .../unordered_set/debug/move_assign_neg.cc | 2 +- .../23_containers/vector/debug/move_assign_neg.cc | 2 +- libstdc++-v3/testsuite/util/testsuite_allocator.h | 342 +++++++++++---------- 12 files changed, 229 insertions(+), 164 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 76b663c5c07..c818e63756d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,30 @@ +2014-07-29 François Dumont + + * testsuite/util/testsuite_allocator.h + (tracker_allocator_counter::allocate): Remove new invocation, only + collect information. + (tracker_allocator_counter::deallocate): Remove delete invocation, only + collect information. + (check_inconsistent_alloc_value_type): New. + (tracker_allocator): Transform as a facade for any allocator type. + (uneq_allocator): Likewise. + (propagating_allocator): Likewise. + * testsuite/23_containers/forward_list/debug/move_assign_neg.cc: Use an + explicitly non propagating allocator. + * testsuite/23_containers/map/debug/move_assign_neg.cc: Likewise. + * testsuite/23_containers/multimap/debug/move_assign_neg.cc: likewise. + * testsuite/23_containers/multiset/debug/move_assign_neg.cc: Likewise. + * testsuite/23_containers/set/debug/move_assign_neg.cc: Likewise. + * testsuite/23_containers/unordered_map/debug/move_assign_neg.cc: + Likewise. + * testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc: + Likewise. + * testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc: + Likewise. + * testsuite/23_containers/unordered_set/debug/move_assign_neg.cc: + Likewise. + * testsuite/23_containers/vector/debug/move_assign_neg.cc: Likewise. + 2014-07-29 Jonathan Wakely PR libstdc++/61946 diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc index 91e459fd3c3..934afbedd6b 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_test::propagating_allocator alloc_type; typedef __gnu_debug::forward_list test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc index 0d63fe944bf..3f2a7ca532b 100644 --- a/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_test::propagating_allocator, + false> alloc_type; typedef __gnu_debug::map, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc index e514a28dbed..da2950fe458 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_test::propagating_allocator, + false> alloc_type; typedef __gnu_debug::multimap, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc index af879d94dad..6f5f5b430cc 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_test::propagating_allocator alloc_type; typedef __gnu_debug::multiset, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc index b7f51efd393..b491a03276d 100644 --- a/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_test::propagating_allocator alloc_type; typedef __gnu_debug::set, alloc_type> test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc index ef5db1165f3..3670f73b0d3 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator > alloc_type; + typedef __gnu_test::propagating_allocator, + false> alloc_type; typedef __gnu_debug::unordered_map, std::equal_to, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc index b6de1eef581..7a8fa77c4d8 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/debug/move_assign_neg.cc @@ -25,7 +25,8 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator> alloc_type; + typedef __gnu_test::propagating_allocator, + false> alloc_type; typedef __gnu_debug::unordered_multimap, std::equal_to, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc index 52a8df2a9f2..9fe72e1f254 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_test::propagating_allocator alloc_type; typedef __gnu_debug::unordered_multiset, std::equal_to, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc index 9d2a8abc425..b1b71e118ff 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/move_assign_neg.cc @@ -25,7 +25,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_test::propagating_allocator alloc_type; typedef __gnu_debug::unordered_set, std::equal_to, alloc_type> test_type; diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc index eb2233b35fe..3de0723195e 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/move_assign_neg.cc @@ -27,7 +27,7 @@ void test01() { bool test __attribute__((unused)) = true; - typedef __gnu_test::uneq_allocator alloc_type; + typedef __gnu_test::propagating_allocator alloc_type; typedef __gnu_debug::vector test_type; test_type v1(alloc_type(1)); diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h index 822a025f4fa..8edc0a5ad78 100644 --- a/libstdc++-v3/testsuite/util/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -29,6 +29,7 @@ #include #include #include +#include #include namespace __gnu_test @@ -38,26 +39,19 @@ namespace __gnu_test public: typedef std::size_t size_type; - static void* + static void allocate(size_type blocksize) - { - void* p = ::operator new(blocksize); - allocationCount_ += blocksize; - return p; - } + { allocationCount_ += blocksize; } static void - construct() { constructCount_++; } + construct() { ++constructCount_; } static void - destroy() { destructCount_++; } + destroy() { ++destructCount_; } static void - deallocate(void* p, size_type blocksize) - { - ::operator delete(p); - deallocationCount_ += blocksize; - } + deallocate(size_type blocksize) + { deallocationCount_ += blocksize; } static size_type get_allocation_count() { return allocationCount_; } @@ -87,103 +81,142 @@ namespace __gnu_test static int destructCount_; }; - // A simple basic allocator that just forwards to the - // tracker_allocator_counter to fulfill memory requests. This class - // is templated on the target object type, but tracker isn't. - template - class tracker_allocator - { - private: - typedef tracker_allocator_counter counter_type; - - public: - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - template struct rebind { typedef tracker_allocator other; }; - - pointer - address(reference value) const _GLIBCXX_NOEXCEPT - { return std::__addressof(value); } + // Helper to detect inconsistency between type used to instantiate an + // allocator and the underlying allocator value_type. + template + struct check_consistent_alloc_value_type; + + template + struct check_consistent_alloc_value_type + { typedef T value_type; }; + + // An allocator facade that intercepts allocate/deallocate/construct/destroy + // calls and track them through the tracker_allocator_counter class. This + // class is templated on the target object type, but tracker isn't. + template > + class tracker_allocator : public Alloc + { + private: + typedef tracker_allocator_counter counter_type; - const_pointer - address(const_reference value) const _GLIBCXX_NOEXCEPT - { return std::__addressof(value); } + typedef __gnu_cxx::__alloc_traits AllocTraits; - tracker_allocator() _GLIBCXX_USE_NOEXCEPT - { } + public: + typedef typename + check_consistent_alloc_value_type::value_type value_type; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; - tracker_allocator(const tracker_allocator&) _GLIBCXX_USE_NOEXCEPT - { } + template + struct rebind + { + typedef tracker_allocator::other> other; + }; + +#if __cplusplus >= 201103L + tracker_allocator() = default; + tracker_allocator(const tracker_allocator&) = default; + tracker_allocator(tracker_allocator&&) = default; + + // Perfect forwarding constructor. + template + tracker_allocator(_Args&&... __args) + : Alloc(std::forward<_Args>(__args)...) + { } +#else + tracker_allocator() + { } - template - tracker_allocator(const tracker_allocator&) _GLIBCXX_USE_NOEXCEPT + tracker_allocator(const tracker_allocator&) { } - ~tracker_allocator() _GLIBCXX_USE_NOEXCEPT - { } + ~tracker_allocator() + { } +#endif - size_type - max_size() const _GLIBCXX_USE_NOEXCEPT - { return size_type(-1) / sizeof(T); } + template + tracker_allocator(const tracker_allocator::other>& alloc) + _GLIBCXX_USE_NOEXCEPT + : Alloc(alloc) + { } - pointer - allocate(size_type n, const void* = 0) - { return static_cast(counter_type::allocate(n * sizeof(T))); } + pointer + allocate(size_type n, const void* = 0) + { + pointer p = AllocTraits::allocate(*this, n); + counter_type::allocate(n * sizeof(T)); + return p; + } #if __cplusplus >= 201103L - template + template + void + construct(U* p, Args&&... args) + { + AllocTraits::construct(*this, p, std::forward(args)...); + counter_type::construct(); + } + + template + void + destroy(U* p) + { + AllocTraits::destroy(*this, p); + counter_type::destroy(); + } +#else void - construct(U* p, Args&&... args) + construct(pointer p, const T& value) { - ::new((void *)p) U(std::forward(args)...); + AllocTraits::construct(*this, p, value); counter_type::construct(); } - template void - destroy(U* p) + destroy(pointer p) { - p->~U(); + AllocTraits::destroy(*this, p); counter_type::destroy(); } -#else - void - construct(pointer p, const T& value) - { - ::new ((void *)p) T(value); - counter_type::construct(); - } - - void - destroy(pointer p) - { - p->~T(); - counter_type::destroy(); - } #endif - void - deallocate(pointer p, size_type num) - { counter_type::deallocate(p, num * sizeof(T)); } - }; + void + deallocate(pointer p, size_type num) + { + counter_type::deallocate(num * sizeof(T)); + AllocTraits::deallocate(*this, p, num); + } + + // Implement swap for underlying allocators that might need it. + friend inline void + swap(tracker_allocator& a, tracker_allocator& b) + { + using std::swap; - template + Alloc& aa = a; + Alloc& ab = b; + swap(aa, ab); + } + }; + + template bool - operator==(const tracker_allocator&, - const tracker_allocator&) throw() - { return true; } + operator==(const tracker_allocator& lhs, + const tracker_allocator& rhs) throw() + { + const Alloc1& alloc1 = lhs; + const Alloc2& alloc2 = rhs; + return lhs == rhs; + } - template + template bool - operator!=(const tracker_allocator&, - const tracker_allocator&) throw() - { return false; } + operator!=(const tracker_allocator& lhs, + const tracker_allocator& rhs) throw() + { return !(lhs == rhs); } bool check_construct_destroy(const char* tag, int expected_c, int expected_d); @@ -193,7 +226,7 @@ namespace __gnu_test check_deallocate_null() { // Let's not core here... - Alloc a; + Alloc a; a.deallocate(0, 1); a.deallocate(0, 10); return true; @@ -219,7 +252,6 @@ namespace __gnu_test throw; } - // A simple allocator which can be constructed endowed of a given // "personality" (an integer), queried in operator== to simulate the // behavior of realworld "unequal" allocators (i.e., not exploiting @@ -227,7 +259,7 @@ namespace __gnu_test // filled at allocation time with (pointer, personality) pairs, is // then consulted to enforce the requirements in Table 32 about // deallocation vs allocator equality. Note that this allocator is - // swappable, not assignable, consistently with Option 3 of DR 431 + // swappable, not copy assignable, consistently with Option 3 of DR 431 // (see N1599). struct uneq_allocator_base { @@ -244,35 +276,49 @@ namespace __gnu_test } }; - template + template > class uneq_allocator - : private uneq_allocator_base + : private uneq_allocator_base, + public Alloc { + typedef __gnu_cxx::__alloc_traits AllocTraits; + + Alloc& base() { return *this; } + const Alloc& base() const { return *this; } + void swap_base(Alloc& b) { swap(b, this->base()); } + public: - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef Tp* pointer; - typedef const Tp* const_pointer; - typedef Tp& reference; - typedef const Tp& const_reference; - typedef Tp value_type; + typedef typename check_consistent_alloc_value_type::value_type + value_type; + typedef typename AllocTraits::size_type size_type; + typedef typename AllocTraits::pointer pointer; #if __cplusplus >= 201103L - typedef std::true_type propagate_on_container_swap; + typedef std::true_type propagate_on_container_swap; #endif template - struct rebind - { typedef uneq_allocator other; }; + struct rebind + { + typedef uneq_allocator::other> other; + }; uneq_allocator() _GLIBCXX_USE_NOEXCEPT : personality(0) { } uneq_allocator(int person) _GLIBCXX_USE_NOEXCEPT : personality(person) { } + +#if __cplusplus >= 201103L + uneq_allocator(const uneq_allocator&) = default; + uneq_allocator(uneq_allocator&&) = default; +#endif template - uneq_allocator(const uneq_allocator& b) _GLIBCXX_USE_NOEXCEPT + uneq_allocator(const uneq_allocator::other>& b) + _GLIBCXX_USE_NOEXCEPT : personality(b.get_personality()) { } ~uneq_allocator() _GLIBCXX_USE_NOEXCEPT @@ -281,20 +327,10 @@ namespace __gnu_test int get_personality() const { return personality; } pointer - address(reference x) const _GLIBCXX_NOEXCEPT - { return std::__addressof(x); } - - const_pointer - address(const_reference x) const _GLIBCXX_NOEXCEPT - { return std::__addressof(x); } - - pointer - allocate(size_type n, const void* = 0) + allocate(size_type n, const void* hint = 0) { - if (__builtin_expect(n > this->max_size(), false)) - std::__throw_bad_alloc(); - - pointer p = static_cast(::operator new(n * sizeof(Tp))); + pointer p = AllocTraits::allocate(*this, n); + try { get_map().insert(map_type::value_type(reinterpret_cast(p), @@ -302,14 +338,15 @@ namespace __gnu_test } catch(...) { - ::operator delete(p); + AllocTraits::deallocate(*this, p, n); __throw_exception_again; } + return p; } void - deallocate(pointer p, size_type) + deallocate(pointer p, size_type n) { bool test __attribute__((unused)) = true; @@ -323,34 +360,18 @@ namespace __gnu_test VERIFY( it->second == personality ); get_map().erase(it); - ::operator delete(p); + AllocTraits::deallocate(*this, p, n); } - size_type - max_size() const _GLIBCXX_USE_NOEXCEPT - { return size_type(-1) / sizeof(Tp); } - #if __cplusplus >= 201103L - template - void - construct(U* p, Args&&... args) - { ::new((void *)p) U(std::forward(args)...); } - - template - void - destroy(U* p) { p->~U(); } - // Not copy assignable... uneq_allocator& operator=(const uneq_allocator&) = delete; -#else - void - construct(pointer p, const Tp& val) - { ::new((void *)p) Tp(val); } - - void - destroy(pointer p) { p->~Tp(); } + // ... but still moveable if base allocator is. + uneq_allocator& + operator=(uneq_allocator&&) = default; +#else private: // Not assignable... uneq_allocator& @@ -358,31 +379,39 @@ namespace __gnu_test #endif private: - // ... yet swappable! friend inline void swap(uneq_allocator& a, uneq_allocator& b) - { std::swap(a.personality, b.personality); } - + { + std::swap(a.personality, b.personality); + a.swap_base(b); + } + template - friend inline bool - operator==(const uneq_allocator& a, const uneq_allocator& b) - { return a.personality == b.personality; } + friend inline bool + operator==(const uneq_allocator& a, + const uneq_allocator::other>& b) + { return a.personality == b.personality; } template - friend inline bool - operator!=(const uneq_allocator& a, const uneq_allocator& b) - { return !(a == b); } + friend inline bool + operator!=(const uneq_allocator& a, + const uneq_allocator::other>& b) + { return !(a == b); } int personality; }; #if __cplusplus >= 201103L // An uneq_allocator which can be used to test allocator propagation. - template - class propagating_allocator : public uneq_allocator + template> + class propagating_allocator : public uneq_allocator { - typedef uneq_allocator base_alloc; + typedef __gnu_cxx::__alloc_traits AllocTraits; + + typedef uneq_allocator base_alloc; base_alloc& base() { return *this; } const base_alloc& base() const { return *this; } void swap_base(base_alloc& b) { swap(b, this->base()); } @@ -393,15 +422,20 @@ namespace __gnu_test // default allocator_traits::rebind_alloc would select // uneq_allocator::rebind so we must define rebind here template - struct rebind { typedef propagating_allocator other; }; + struct rebind + { + typedef propagating_allocator::other> other; + }; propagating_allocator(int i) noexcept : base_alloc(i) { } template - propagating_allocator(const propagating_allocator& a) - noexcept + propagating_allocator(const propagating_allocator::other>& a) + noexcept : base_alloc(a) { } @@ -418,8 +452,8 @@ namespace __gnu_test } template - propagating_allocator& - operator=(const propagating_allocator& a) noexcept + propagating_allocator& + operator=(const propagating_allocator& a) noexcept { static_assert(P2, "assigning propagating_allocator"); propagating_allocator(a).swap_base(*this); -- 2.11.4.GIT