Gentle reminder, we still have this issue pending.
* include/bits/hashtable_policy.h
(_Hashtable_alloc<>::_M_deallocate_node_ptr(__node_type*)): New.
(_Hashtable_alloc<>::_M_deallocate_node(__node_type*)): Use latter.
(_ReuseOrAllocNode<>::operator<_Arg>()(_Arg&&)): Likewise.
* libstdc++-v3/testsuite/util/testsuite_allocator.h
(CustomPointerAlloc<>::allocate(size_t, pointer)): Replace by...
(CustomPointerAlloc<>::allocate(size_t, const_void_pointer)): ...this.
François
On 11/29/18 7:08 AM, François Dumont wrote:
I am unclear about this patch, is it accepted ?
On 11/19/18 10:19 PM, François Dumont wrote:
On 11/19/18 1:34 PM, Jonathan Wakely wrote:
On 10/11/18 22:40 +0100, François Dumont wrote:
While working on a hashtable enhancement I noticed that we are not
using the correct method to deallocate node if the constructor
throws in _ReuseOrAllocNode operator(). I had to introduce a new
_M_deallocate_node_ptr for that as node value shall not be destroy
again.
I also check other places and noticed that a __node_type destructor
call was missing.
That's intentional. The type has a trivial destructor, so its storage
can just be reused, we don't need to destroy it.
Ok, do you want to also remove the other call to ~__node_type() then ?
Here is the updated patch and the right ChangeLog entry:
* include/bits/hashtable_policy.h
(_Hashtable_alloc<>::_M_deallocate_node_ptr(__node_type*)): New.
(_Hashtable_alloc<>::_M_deallocate_node(__node_type*)): Use latter.
(_ReuseOrAllocNode<>::operator<_Arg>()(_Arg&&)): Likewise.
(_Hashtable_alloc<>::_M_allocate_node): Add ~__node_type call.
* libstdc++-v3/testsuite/util/testsuite_allocator.h
(CustomPointerAlloc<>::allocate(size_t, pointer)): Replace by...
(CustomPointerAlloc<>::allocate(size_t, const_void_pointer)):
...this.
* testsuite/23_containers/unordered_set/allocator/ext_ptr.cc: Add
check.
Ok to commit ?
François
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index b843c955797..aa4808eab31 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -148,8 +148,7 @@ namespace __detail
}
__catch(...)
{
- __node->~__node_type();
- __node_alloc_traits::deallocate(__a, __node, 1);
+ _M_h._M_deallocate_node_ptr(__node);
__throw_exception_again;
}
return __node;
@@ -2116,6 +2115,9 @@ namespace __detail
void
_M_deallocate_node(__node_type* __n);
+ void
+ _M_deallocate_node_ptr(__node_type* __n);
+
// Deallocate the linked list of nodes pointed to by __n
void
_M_deallocate_nodes(__node_type* __n);
@@ -2154,10 +2156,17 @@ namespace __detail
template<typename _NodeAlloc>
void
_Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n)
+ {
+ __node_alloc_traits::destroy(_M_node_allocator(), __n->_M_valptr());
+ _M_deallocate_node_ptr(__n);
+ }
+
+ template<typename _NodeAlloc>
+ void
+ _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node_ptr(__node_type* __n)
{
typedef typename __node_alloc_traits::pointer _Ptr;
auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
- __node_alloc_traits::destroy(_M_node_allocator(), __n->_M_valptr());
__n->~__node_type();
__node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
}
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index b0fecfb59a3..c18223475c9 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -582,7 +582,7 @@ namespace __gnu_test
typedef Ptr<void> void_pointer;
typedef Ptr<const void> const_void_pointer;
- pointer allocate(std::size_t n, pointer = {})
+ pointer allocate(std::size_t n, const_void_pointer = {})
{ return pointer(std::allocator<Tp>::allocate(n)); }
void deallocate(pointer p, std::size_t n)