Quuxplusone created this revision. `pointer_traits<P>::to_pointer(r)` is not required to return a deallocatable pointer; indeed generally it *cannot* determine a deallocatable representation without help from the allocator. Therefore, we must not rely on representations derived from `to_pointer` when deallocating; we must pass to `deallocate` the exact same pointer (or at least a pointer linearly derived from the pointer) that we originally received from `allocate`.
I have an example fancy-pointer allocator here which might be convertible into a test case: https://github.com/Quuxplusone/from-scratch/blob/master/include/scratch/bits/containers/segmented-allocator.h https://reviews.llvm.org/D35863 Files: include/list
Index: include/list =================================================================== --- include/list +++ include/list @@ -728,7 +728,7 @@ __sz() = 0; while (__f != __l) { - __node_pointer __np = __f->__as_node(); + __node_pointer __np = static_cast<__node_pointer>(__f); __f = __f->__next_; __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_alloc_traits::deallocate(__na, __np, 1); @@ -1389,10 +1389,12 @@ #endif __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link()); + __link_pointer __nl = static_cast<__link_pointer>(__np); + __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__hold.release()->__as_link(), this); @@ -1418,26 +1420,29 @@ size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); ++__ds; + __link_pointer __nl = static_cast<__link_pointer>(__np); + __hold.release(); #if _LIBCPP_DEBUG_LEVEL >= 2 - __r = iterator(__hold->__as_link(), this); + iterator __r = iterator(__nl, this); #else - __r = iterator(__hold->__as_link()); + iterator __r = iterator(__nl); #endif - __hold.release(); iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (--__n; __n != 0; --__n, ++__e, ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __np = __node_alloc_traits::allocate(__na, 1); + __hold.reset(__np); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __e.__ptr_->__next_ = __hold->__as_link(); + __e.__ptr_->__next_ = __np; __hold->__prev_ = __e.__ptr_; __hold.release(); } @@ -1449,7 +1454,7 @@ { __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_alloc_traits::deallocate(__na, static_cast<__node_pointer>(__e.__ptr_), 1); if (__prev == 0) break; #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1486,26 +1491,29 @@ size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); ++__ds; + __link_pointer __nl = static_cast<__link_pointer>(__np); + __hold.release(); #if _LIBCPP_DEBUG_LEVEL >= 2 - __r = iterator(__hold.get()->__as_link(), this); + iterator __r = iterator(__nl, this); #else - __r = iterator(__hold.get()->__as_link()); + iterator __r = iterator(__nl); #endif - __hold.release(); iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (++__f; __f != __l; ++__f, (void) ++__e, (void) ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __np = __node_alloc_traits::allocate(__na, 1); + __hold.reset(__np); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); - __e.__ptr_->__next_ = __hold.get()->__as_link(); + __e.__ptr_->__next_ = __np; __hold->__prev_ = __e.__ptr_; __hold.release(); } @@ -1517,7 +1525,7 @@ { __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_alloc_traits::deallocate(__na, static_cast<__node_pointer>(__e.__ptr_), 1); if (__prev == 0) break; #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1541,9 +1549,10 @@ { __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_pointer __nl = __hold->__as_link(); + __link_pointer __nl = static_cast<__link_pointer>(__np); __link_nodes_at_front(__nl, __nl); ++base::__sz(); __hold.release(); @@ -1555,9 +1564,11 @@ { __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); - __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); + __link_pointer __nl = static_cast<__link_pointer>(__np); + __link_nodes_at_back(__nl, __nl); ++base::__sz(); __hold.release(); } @@ -1570,9 +1581,11 @@ { __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); + __link_pointer __nl = static_cast<__link_pointer>(__np); + __link_nodes_at_front(__nl, __nl); ++base::__sz(); __hold.release(); } @@ -1583,9 +1596,11 @@ { __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_nodes_at_back(__hold.get()->__as_link(), __hold.get()->__as_link()); + __link_pointer __nl = static_cast<__link_pointer>(__np); + __link_nodes_at_back(__nl, __nl); ++base::__sz(); __hold.release(); } @@ -1601,9 +1616,11 @@ { __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); + __link_pointer __nl = static_cast<__link_pointer>(__np); + __link_nodes_at_front(__nl, __nl); ++base::__sz(); #if _LIBCPP_STD_VER > 14 return __hold.release()->__value_; @@ -1623,9 +1640,10 @@ { __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_pointer __nl = __hold->__as_link(); + __link_pointer __nl = static_cast<__link_pointer>(__np); __link_nodes_at_back(__nl, __nl); ++base::__sz(); #if _LIBCPP_STD_VER > 14 @@ -1647,10 +1665,11 @@ #endif __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); - __link_pointer __nl = __hold.get()->__as_link(); + __link_pointer __nl = static_cast<__link_pointer>(__np); __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); __hold.release(); @@ -1672,10 +1691,11 @@ #endif __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); - __link_pointer __nl = __hold->__as_link(); + __link_pointer __nl = static_cast<__link_pointer>(__np); __link_nodes(__p.__ptr_, __nl, __nl); ++base::__sz(); __hold.release(); @@ -1712,7 +1732,7 @@ } __get_db()->unlock(); #endif - __node_pointer __np = __n->__as_node(); + __node_pointer __np = static_cast<__node_pointer>(__n); __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_alloc_traits::deallocate(__na, __np, 1); } @@ -1741,7 +1761,7 @@ } __get_db()->unlock(); #endif - __node_pointer __np = __n->__as_node(); + __node_pointer __np = static_cast<__node_pointer>(__n); __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_alloc_traits::deallocate(__na, __np, 1); } @@ -1777,7 +1797,7 @@ } __get_db()->unlock(); #endif - __node_pointer __np = __n->__as_node(); + __node_pointer __np = static_cast<__node_pointer>(__n); __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_alloc_traits::deallocate(__na, __np, 1); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1823,7 +1843,7 @@ } __get_db()->unlock(); #endif - __node_pointer __np = __n->__as_node(); + __node_pointer __np = static_cast<__node_pointer>(__n); __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_alloc_traits::deallocate(__na, __np, 1); } @@ -1847,25 +1867,29 @@ size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); ++__ds; + __link_pointer __nl = static_cast<__link_pointer>(__np); + __hold.release(); #if _LIBCPP_DEBUG_LEVEL >= 2 - iterator __r = iterator(__hold.release()->__as_link(), this); + iterator __r = iterator(__nl, this); #else - iterator __r = iterator(__hold.release()->__as_link()); + iterator __r = iterator(__nl); #endif iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (--__n; __n != 0; --__n, ++__e, ++__ds) { - __hold.reset(__node_alloc_traits::allocate(__na, 1)); + __np = __node_alloc_traits::allocate(__na, 1); + __hold.reset(__np); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); - __e.__ptr_->__next_ = __hold.get()->__as_link(); + __e.__ptr_->__next_ = static_cast<__link_pointer>(__np); __hold->__prev_ = __e.__ptr_; __hold.release(); } @@ -1877,7 +1901,7 @@ { __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_alloc_traits::deallocate(__na, static_cast<__node_pointer>(__e.__ptr_), 1); if (__prev == 0) break; #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1906,11 +1930,13 @@ size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); + __node_pointer __np = __node_alloc_traits::allocate(__na, 1); + unique_ptr<__node, _Dp> __hold(__np, _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); ++__ds; - __link_pointer __nl = __hold.release()->__as_link(); + __link_pointer __nl = static_cast<__link_pointer>(__np); + __hold.release(); #if _LIBCPP_DEBUG_LEVEL >= 2 iterator __r = iterator(__nl, this); #else @@ -1937,7 +1963,7 @@ { __node_alloc_traits::destroy(__na, _VSTD::addressof(*__e)); __link_pointer __prev = __e.__ptr_->__prev_; - __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); + __node_alloc_traits::deallocate(__na, static_cast<__node_pointer>(__e.__ptr_), 1); if (__prev == 0) break; #if _LIBCPP_DEBUG_LEVEL >= 2
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits