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

Reply via email to