[libcxx-commits] [libcxx] [libc++] Take the ABI break for `std::list`'s pointer UB unconditionally (PR #100585)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sat Aug 17 01:47:39 PDT 2024


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/100585

>From 8ce53cbdfc9fe8d0df609f351b5002ba5e153aa7 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 19 Jul 2024 09:28:34 +0200
Subject: [PATCH] [libc++] Take the ABI break for  unconditionally

---
 libcxx/docs/ReleaseNotes/20.rst |   7 +-
 libcxx/include/__hash_table     |  14 +++-
 libcxx/include/__tree           |  19 +++--
 libcxx/include/forward_list     |  28 +++----
 libcxx/include/list             | 140 ++++++++++++++++----------------
 5 files changed, 108 insertions(+), 100 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index fb677b1667ddcf..bd8cb0f26f129d 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -72,8 +72,11 @@ LLVM 21
 ABI Affecting Changes
 ---------------------
 
-- TODO
-
+- The ABI breaks for removing undefined behaviour in ``std::forward_list``, ``std::list``, ``std::map``, ``std::set``,
+  ``std::multimap``, ``std::multiset``, ``std::unordered_map``, ``std::unordered_set``, ``std::unordered_multimap`` and
+  ``std::unordered_multiset`` are now applied unconditionally. This only affects fancy pointers which have a different
+  value representation when pointing at the base of an internal node type instead of the type itself. A size or alinment
+  difference is diagnosed, but more subtle ABI breaks may result in unexpected behaviour.
 
 Build System Changes
 --------------------
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 025758528573f2..aa4839ce9e7cdb 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -77,11 +77,17 @@ struct __hash_node_base {
   typedef __hash_node_base __first_node;
   typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer;
   typedef _NodePtr __node_pointer;
-
-#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
   typedef __node_base_pointer __next_pointer;
-#else
-  typedef __conditional_t<is_pointer<__node_pointer>::value, __node_base_pointer, __node_pointer> __next_pointer;
+
+#ifndef _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
+  static_assert(sizeof(__node_base_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__node_base_pointer) ==
+                    _LIBCPP_ALIGNOF(__node_pointer),
+                "It looks like you are using std::__hash_table (an implementation detail for the unordered containers) "
+                "with a fancy pointer type that thas a different representation depending on whether it points to a "
+                "__tree base pointer or a __tree node pointer (both of which are implementation details of the "
+                "standard library). This means that your ABI is being broken between LLVM 19 and LLVM 20. If you don't "
+                "care about your ABI being broken, define the _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB macro do silence "
+                "this diagnostic.");
 #endif
 
   __next_pointer __next_;
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 1990fa602d39ca..ddc5b1f22c2978 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -566,11 +566,17 @@ struct __tree_node_base_types {
 
   typedef __tree_end_node<__node_base_pointer> __end_node_type;
   typedef __rebind_pointer_t<_VoidPtr, __end_node_type> __end_node_pointer;
-#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
   typedef __end_node_pointer __parent_pointer;
-#else
-  typedef __conditional_t< is_pointer<__end_node_pointer>::value, __end_node_pointer, __node_base_pointer>
-      __parent_pointer;
+
+#ifndef _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
+  static_assert(sizeof(__node_base_pointer) == sizeof(__end_node_pointer) && _LIBCPP_ALIGNOF(__node_base_pointer) ==
+                    _LIBCPP_ALIGNOF(__end_node_pointer),
+                "It looks like you are using std::__tree (an implementation detail for (multi)map/set) with a fancy "
+                "pointer type that thas a different representation depending on whether it points to a __tree base "
+                "pointer or a __tree node pointer (both of which are implementation details of the standard library). "
+                "This means that your ABI is being broken between LLVM 19 and LLVM 20. If you don't care about your "
+                "ABI being broken, define the _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB macro do silence this "
+                "diagnostic.");
 #endif
 
 private:
@@ -605,12 +611,7 @@ public:
   typedef _Tp __node_value_type;
   typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer;
   typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
-#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB)
   typedef typename __base::__end_node_pointer __iter_pointer;
-#else
-  typedef __conditional_t< is_pointer<__node_pointer>::value, typename __base::__end_node_pointer, __node_pointer>
-      __iter_pointer;
-#endif
 
 private:
   static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const");
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index b14d2cb6c78036..5ec5dcc9d6fbb1 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -276,18 +276,20 @@ struct __forward_node_traits {
   typedef __rebind_pointer_t<_NodePtr, __begin_node> __begin_node_pointer;
   typedef __rebind_pointer_t<_NodePtr, void> __void_pointer;
 
-#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB)
-  typedef __begin_node_pointer __iter_node_pointer;
-#else
-  typedef __conditional_t<is_pointer<__void_pointer>::value, __begin_node_pointer, __node_pointer> __iter_node_pointer;
+  // TODO(LLVM 22): Remove this check
+#ifndef _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
+  static_assert(sizeof(__begin_node_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__begin_node_pointer) ==
+                    _LIBCPP_ALIGNOF(__node_pointer),
+                "It looks like you are using std::forward_list with a fancy pointer type that thas a different "
+                "representation depending on whether it points to a forward_list base pointer or a forward_list node "
+                "pointer (both of which are implementation details of the standard library). This means that your ABI "
+                "is being broken between LLVM 19 and LLVM 20. If you don't care about your ABI being broken, define "
+                "the _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB macro do silence this diagnostic.");
 #endif
 
-  typedef __conditional_t<is_same<__iter_node_pointer, __node_pointer>::value, __begin_node_pointer, __node_pointer>
-      __non_iter_node_pointer;
-
-  _LIBCPP_HIDE_FROM_ABI static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { return __p; }
-  _LIBCPP_HIDE_FROM_ABI static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) {
-    return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p));
+  _LIBCPP_HIDE_FROM_ABI static __begin_node_pointer __as_iter_node(__begin_node_pointer __p) { return __p; }
+  _LIBCPP_HIDE_FROM_ABI static __begin_node_pointer __as_iter_node(__node_pointer __p) {
+    return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__p));
   }
 };
 
@@ -349,10 +351,9 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_iterator {
   typedef __forward_node_traits<_NodePtr> __traits;
   typedef typename __traits::__node_pointer __node_pointer;
   typedef typename __traits::__begin_node_pointer __begin_node_pointer;
-  typedef typename __traits::__iter_node_pointer __iter_node_pointer;
   typedef typename __traits::__void_pointer __void_pointer;
 
-  __iter_node_pointer __ptr_;
+  __begin_node_pointer __ptr_;
 
   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
     return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__ptr_));
@@ -415,10 +416,9 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator {
   typedef typename __traits::__node_type __node_type;
   typedef typename __traits::__node_pointer __node_pointer;
   typedef typename __traits::__begin_node_pointer __begin_node_pointer;
-  typedef typename __traits::__iter_node_pointer __iter_node_pointer;
   typedef typename __traits::__void_pointer __void_pointer;
 
-  __iter_node_pointer __ptr_;
+  __begin_node_pointer __ptr_;
 
   _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const {
     return static_cast<__begin_node_pointer>(static_cast<__void_pointer>(__ptr_));
diff --git a/libcxx/include/list b/libcxx/include/list
index 929c84de7be449..d21c219c7c6e7c 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -271,19 +271,20 @@ struct __list_node_pointer_traits {
   typedef __rebind_pointer_t<_VoidPtr, __list_node<_Tp, _VoidPtr> > __node_pointer;
   typedef __rebind_pointer_t<_VoidPtr, __list_node_base<_Tp, _VoidPtr> > __base_pointer;
 
-#if defined(_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB)
-  typedef __base_pointer __link_pointer;
-#else
-  typedef __conditional_t<is_pointer<_VoidPtr>::value, __base_pointer, __node_pointer> __link_pointer;
+#ifndef _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
+  static_assert(sizeof(__node_pointer) == sizeof(__node_pointer) && _LIBCPP_ALIGNOF(__base_pointer) ==
+                    _LIBCPP_ALIGNOF(__node_pointer),
+                "It looks like you are using std::list with a fancy pointer type that thas a different representation "
+                "depending on whether it points to a list base pointer or a list node pointer (both of which are "
+                "implementation details of the standard library). This means that your ABI is being broken between "
+                "LLVM 19 and LLVM 20. If you don't care about your ABI being broken, define the "
+                "_LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB macro do silence this diagnostic.");
 #endif
 
-  typedef __conditional_t<is_same<__link_pointer, __node_pointer>::value, __base_pointer, __node_pointer>
-      __non_link_pointer;
-
-  static _LIBCPP_HIDE_FROM_ABI __link_pointer __unsafe_link_pointer_cast(__link_pointer __p) { return __p; }
+  static _LIBCPP_HIDE_FROM_ABI __base_pointer __unsafe_link_pointer_cast(__base_pointer __p) { return __p; }
 
-  static _LIBCPP_HIDE_FROM_ABI __link_pointer __unsafe_link_pointer_cast(__non_link_pointer __p) {
-    return static_cast<__link_pointer>(static_cast<_VoidPtr>(__p));
+  static _LIBCPP_HIDE_FROM_ABI __base_pointer __unsafe_link_pointer_cast(__node_pointer __p) {
+    return static_cast<__base_pointer>(static_cast<_VoidPtr>(__p));
   }
 };
 
@@ -292,16 +293,13 @@ struct __list_node_base {
   typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
   typedef typename _NodeTraits::__node_pointer __node_pointer;
   typedef typename _NodeTraits::__base_pointer __base_pointer;
-  typedef typename _NodeTraits::__link_pointer __link_pointer;
 
-  __link_pointer __prev_;
-  __link_pointer __next_;
+  __base_pointer __prev_;
+  __base_pointer __next_;
 
-  _LIBCPP_HIDE_FROM_ABI __list_node_base()
-      : __prev_(_NodeTraits::__unsafe_link_pointer_cast(__self())),
-        __next_(_NodeTraits::__unsafe_link_pointer_cast(__self())) {}
+  _LIBCPP_HIDE_FROM_ABI __list_node_base() : __prev_(__self()), __next_(__self()) {}
 
-  _LIBCPP_HIDE_FROM_ABI explicit __list_node_base(__link_pointer __prev, __link_pointer __next)
+  _LIBCPP_HIDE_FROM_ABI explicit __list_node_base(__base_pointer __prev, __base_pointer __next)
       : __prev_(__prev), __next_(__next) {}
 
   _LIBCPP_HIDE_FROM_ABI __base_pointer __self() { return pointer_traits<__base_pointer>::pointer_to(*this); }
@@ -332,12 +330,12 @@ public:
 #endif
 
   typedef __list_node_base<_Tp, _VoidPtr> __base;
-  typedef typename __base::__link_pointer __link_pointer;
+  typedef typename __base::__base_pointer __base_pointer;
 
-  _LIBCPP_HIDE_FROM_ABI explicit __list_node(__link_pointer __prev, __link_pointer __next) : __base(__prev, __next) {}
+  _LIBCPP_HIDE_FROM_ABI explicit __list_node(__base_pointer __prev, __base_pointer __next) : __base(__prev, __next) {}
   _LIBCPP_HIDE_FROM_ABI ~__list_node() {}
 
-  _LIBCPP_HIDE_FROM_ABI __link_pointer __as_link() { return static_cast<__link_pointer>(__base::__self()); }
+  _LIBCPP_HIDE_FROM_ABI __base_pointer __as_link() { return __base::__self(); }
 };
 
 template <class _Tp, class _Alloc = allocator<_Tp> >
@@ -350,11 +348,11 @@ class _LIBCPP_TEMPLATE_VIS __list_const_iterator;
 template <class _Tp, class _VoidPtr>
 class _LIBCPP_TEMPLATE_VIS __list_iterator {
   typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
-  typedef typename _NodeTraits::__link_pointer __link_pointer;
+  typedef typename _NodeTraits::__base_pointer __base_pointer;
 
-  __link_pointer __ptr_;
+  __base_pointer __ptr_;
 
-  _LIBCPP_HIDE_FROM_ABI explicit __list_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+  _LIBCPP_HIDE_FROM_ABI explicit __list_iterator(__base_pointer __p) _NOEXCEPT : __ptr_(__p) {}
 
   template <class, class>
   friend class list;
@@ -408,11 +406,11 @@ public:
 template <class _Tp, class _VoidPtr>
 class _LIBCPP_TEMPLATE_VIS __list_const_iterator {
   typedef __list_node_pointer_traits<_Tp, _VoidPtr> _NodeTraits;
-  typedef typename _NodeTraits::__link_pointer __link_pointer;
+  typedef typename _NodeTraits::__base_pointer __base_pointer;
 
-  __link_pointer __ptr_;
+  __base_pointer __ptr_;
 
-  _LIBCPP_HIDE_FROM_ABI explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT : __ptr_(__p) {}
+  _LIBCPP_HIDE_FROM_ABI explicit __list_const_iterator(__base_pointer __p) _NOEXCEPT : __ptr_(__p) {}
 
   template <class, class>
   friend class list;
@@ -485,8 +483,8 @@ protected:
   typedef typename __node_alloc_traits::pointer __node_pointer;
   typedef typename __node_alloc_traits::pointer __node_const_pointer;
   typedef __list_node_pointer_traits<value_type, __void_pointer> __node_pointer_traits;
-  typedef typename __node_pointer_traits::__link_pointer __link_pointer;
-  typedef __link_pointer __link_const_pointer;
+  typedef typename __node_pointer_traits::__base_pointer __base_pointer;
+  typedef __base_pointer __link_const_pointer;
   typedef typename __alloc_traits::pointer pointer;
   typedef typename __alloc_traits::const_pointer const_pointer;
   typedef typename __alloc_traits::difference_type difference_type;
@@ -499,7 +497,7 @@ protected:
   __node_base __end_;
   __compressed_pair<size_type, __node_allocator> __size_alloc_;
 
-  _LIBCPP_HIDE_FROM_ABI __link_pointer __end_as_link() const _NOEXCEPT {
+  _LIBCPP_HIDE_FROM_ABI __base_pointer __end_as_link() const _NOEXCEPT {
     return __node_pointer_traits::__unsafe_link_pointer_cast(const_cast<__node_base&>(__end_).__self());
   }
 
@@ -511,7 +509,7 @@ protected:
   _LIBCPP_HIDE_FROM_ABI size_type __node_alloc_max_size() const _NOEXCEPT {
     return __node_alloc_traits::max_size(__node_alloc());
   }
-  _LIBCPP_HIDE_FROM_ABI static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI static void __unlink_nodes(__base_pointer __f, __base_pointer __l) _NOEXCEPT;
 
   _LIBCPP_HIDE_FROM_ABI __list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value);
   _LIBCPP_HIDE_FROM_ABI __list_imp(const allocator_type& __a);
@@ -548,7 +546,7 @@ protected:
   }
 
   template <class... _Args>
-  _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__link_pointer __prev, __link_pointer __next, _Args&&... __args) {
+  _LIBCPP_HIDE_FROM_ABI __node_pointer __create_node(__base_pointer __prev, __base_pointer __next, _Args&&... __args) {
     __node_allocator& __alloc = __node_alloc();
     __allocation_guard<__node_allocator> __guard(__alloc, 1);
     // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
@@ -593,7 +591,7 @@ private:
 
 // Unlink nodes [__f, __l]
 template <class _Tp, class _Alloc>
-inline void __list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT {
+inline void __list_imp<_Tp, _Alloc>::__unlink_nodes(__base_pointer __f, __base_pointer __l) _NOEXCEPT {
   __f->__prev_->__next_ = __l->__next_;
   __l->__next_->__prev_ = __f->__prev_;
 }
@@ -621,8 +619,8 @@ __list_imp<_Tp, _Alloc>::~__list_imp() {
 template <class _Tp, class _Alloc>
 void __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT {
   if (!empty()) {
-    __link_pointer __f = __end_.__next_;
-    __link_pointer __l = __end_as_link();
+    __base_pointer __f = __end_.__next_;
+    __base_pointer __l = __end_as_link();
     __unlink_nodes(__f, __l->__prev_);
     __sz() = 0;
     while (__f != __l) {
@@ -668,7 +666,7 @@ class _LIBCPP_TEMPLATE_VIS list : private __list_imp<_Tp, _Alloc> {
   typedef typename base::__node_alloc_traits __node_alloc_traits;
   typedef typename base::__node_base __node_base;
   typedef typename base::__node_base_pointer __node_base_pointer;
-  typedef typename base::__link_pointer __link_pointer;
+  typedef typename base::__base_pointer __base_pointer;
 
 public:
   typedef _Tp value_type;
@@ -917,9 +915,9 @@ private:
   template <class _Iterator, class _Sentinel>
   _LIBCPP_HIDE_FROM_ABI iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l);
 
-  _LIBCPP_HIDE_FROM_ABI static void __link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l);
-  _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_front(__link_pointer __f, __link_pointer __l);
-  _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_back(__link_pointer __f, __link_pointer __l);
+  _LIBCPP_HIDE_FROM_ABI static void __link_nodes(__base_pointer __p, __base_pointer __f, __base_pointer __l);
+  _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_front(__base_pointer __f, __base_pointer __l);
+  _LIBCPP_HIDE_FROM_ABI void __link_nodes_at_back(__base_pointer __f, __base_pointer __l);
   _LIBCPP_HIDE_FROM_ABI iterator __iterator(size_type __n);
   // TODO: Make this _LIBCPP_HIDE_FROM_ABI
   template <class _Comp>
@@ -953,7 +951,7 @@ list(from_range_t, _Range&&, _Alloc = _Alloc()) -> list<ranges::range_value_t<_R
 
 // Link in nodes [__f, __l] just prior to __p
 template <class _Tp, class _Alloc>
-inline void list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l) {
+inline void list<_Tp, _Alloc>::__link_nodes(__base_pointer __p, __base_pointer __f, __base_pointer __l) {
   __p->__prev_->__next_ = __f;
   __f->__prev_          = __p->__prev_;
   __p->__prev_          = __l;
@@ -962,7 +960,7 @@ inline void list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer _
 
 // Link in nodes [__f, __l] at the front of the list
 template <class _Tp, class _Alloc>
-inline void list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) {
+inline void list<_Tp, _Alloc>::__link_nodes_at_front(__base_pointer __f, __base_pointer __l) {
   __f->__prev_          = base::__end_as_link();
   __l->__next_          = base::__end_.__next_;
   __l->__next_->__prev_ = __l;
@@ -971,7 +969,7 @@ inline void list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_
 
 // Link in nodes [__f, __l] at the back of the list
 template <class _Tp, class _Alloc>
-inline void list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) {
+inline void list<_Tp, _Alloc>::__link_nodes_at_back(__base_pointer __f, __base_pointer __l) {
   __l->__next_          = base::__end_as_link();
   __f->__prev_          = base::__end_.__prev_;
   __f->__prev_->__next_ = __f;
@@ -1163,7 +1161,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
       while (true) {
-        __link_pointer __prev    = __e.__ptr_->__prev_;
+        __base_pointer __prev    = __e.__ptr_->__prev_;
         __node_pointer __current = __e.__ptr_->__as_node();
         this->__delete_node(__current);
         if (__prev == 0)
@@ -1205,7 +1203,7 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
       while (true) {
-        __link_pointer __prev    = __e.__ptr_->__prev_;
+        __base_pointer __prev    = __e.__ptr_->__prev_;
         __node_pointer __current = __e.__ptr_->__as_node();
         this->__delete_node(__current);
         if (__prev == 0)
@@ -1224,7 +1222,7 @@ list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Se
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::push_front(const value_type& __x) {
   __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, __x);
-  __link_pointer __nl   = __node->__as_link();
+  __base_pointer __nl   = __node->__as_link();
   __link_nodes_at_front(__nl, __nl);
   ++base::__sz();
 }
@@ -1232,7 +1230,7 @@ void list<_Tp, _Alloc>::push_front(const value_type& __x) {
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::push_back(const value_type& __x) {
   __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, __x);
-  __link_pointer __nl   = __node->__as_link();
+  __base_pointer __nl   = __node->__as_link();
   __link_nodes_at_back(__nl, __nl);
   ++base::__sz();
 }
@@ -1242,7 +1240,7 @@ void list<_Tp, _Alloc>::push_back(const value_type& __x) {
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::push_front(value_type&& __x) {
   __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::move(__x));
-  __link_pointer __nl   = __node->__as_link();
+  __base_pointer __nl   = __node->__as_link();
   __link_nodes_at_front(__nl, __nl);
   ++base::__sz();
 }
@@ -1250,7 +1248,7 @@ void list<_Tp, _Alloc>::push_front(value_type&& __x) {
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::push_back(value_type&& __x) {
   __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::move(__x));
-  __link_pointer __nl   = __node->__as_link();
+  __base_pointer __nl   = __node->__as_link();
   __link_nodes_at_back(__nl, __nl);
   ++base::__sz();
 }
@@ -1265,7 +1263,7 @@ void
 list<_Tp, _Alloc>::emplace_front(_Args&&... __args) {
   __node_pointer __node =
       this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::forward<_Args>(__args)...);
-  __link_pointer __nl = __node->__as_link();
+  __base_pointer __nl = __node->__as_link();
   __link_nodes_at_front(__nl, __nl);
   ++base::__sz();
 #  if _LIBCPP_STD_VER >= 17
@@ -1283,7 +1281,7 @@ void
 list<_Tp, _Alloc>::emplace_back(_Args&&... __args) {
   __node_pointer __node =
       this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::forward<_Args>(__args)...);
-  __link_pointer __nl = __node->__as_link();
+  __base_pointer __nl = __node->__as_link();
   __link_nodes_at_back(__nl, __nl);
   ++base::__sz();
 #  if _LIBCPP_STD_VER >= 17
@@ -1296,7 +1294,7 @@ template <class... _Args>
 typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) {
   __node_pointer __node =
       this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::forward<_Args>(__args)...);
-  __link_pointer __nl = __node->__as_link();
+  __base_pointer __nl = __node->__as_link();
   __link_nodes(__p.__ptr_, __nl, __nl);
   ++base::__sz();
   return iterator(__nl);
@@ -1305,7 +1303,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator _
 template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) {
   __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, std::move(__x));
-  __link_pointer __nl   = __node->__as_link();
+  __base_pointer __nl   = __node->__as_link();
   __link_nodes(__p.__ptr_, __nl, __nl);
   ++base::__sz();
   return iterator(__nl);
@@ -1316,7 +1314,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::pop_front() {
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_front() called with empty list");
-  __link_pointer __n = base::__end_.__next_;
+  __base_pointer __n = base::__end_.__next_;
   base::__unlink_nodes(__n, __n);
   --base::__sz();
   this->__delete_node(__n->__as_node());
@@ -1325,7 +1323,7 @@ void list<_Tp, _Alloc>::pop_front() {
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::pop_back() {
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_back() called on an empty list");
-  __link_pointer __n = base::__end_.__prev_;
+  __base_pointer __n = base::__end_.__prev_;
   base::__unlink_nodes(__n, __n);
   --base::__sz();
   this->__delete_node(__n->__as_node());
@@ -1334,8 +1332,8 @@ void list<_Tp, _Alloc>::pop_back() {
 template <class _Tp, class _Alloc>
 typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) {
   _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(), "list::erase(iterator) called with a non-dereferenceable iterator");
-  __link_pointer __n = __p.__ptr_;
-  __link_pointer __r = __n->__next_;
+  __base_pointer __n = __p.__ptr_;
+  __base_pointer __r = __n->__next_;
   base::__unlink_nodes(__n, __n);
   --base::__sz();
   this->__delete_node(__n->__as_node());
@@ -1347,7 +1345,7 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __f
   if (__f != __l) {
     base::__unlink_nodes(__f.__ptr_, __l.__ptr_->__prev_);
     while (__f != __l) {
-      __link_pointer __n = __f.__ptr_;
+      __base_pointer __n = __f.__ptr_;
       ++__f;
       --base::__sz();
       this->__delete_node(__n->__as_node());
@@ -1376,7 +1374,7 @@ void list<_Tp, _Alloc>::resize(size_type __n) {
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
       while (true) {
-        __link_pointer __prev    = __e.__ptr_->__prev_;
+        __base_pointer __prev    = __e.__ptr_->__prev_;
         __node_pointer __current = __e.__ptr_->__as_node();
         this->__delete_node(__current);
         if (__prev == 0)
@@ -1400,7 +1398,7 @@ void list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) {
     size_type __ds        = 0;
     __node_pointer __node = this->__create_node(/* prev = */ nullptr, /* next = */ nullptr, __x);
     ++__ds;
-    __link_pointer __nl = __node->__as_link();
+    __base_pointer __nl = __node->__as_link();
     iterator __r        = iterator(__nl);
     iterator __e        = __r;
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
@@ -1412,7 +1410,7 @@ void list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) {
 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
     } catch (...) {
       while (true) {
-        __link_pointer __prev    = __e.__ptr_->__prev_;
+        __base_pointer __prev    = __e.__ptr_->__prev_;
         __node_pointer __current = __e.__ptr_->__as_node();
         this->__delete_node(__current);
         if (__prev == 0)
@@ -1432,8 +1430,8 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) {
   _LIBCPP_ASSERT_VALID_INPUT_RANGE(
       this != std::addressof(__c), "list::splice(iterator, list) called with this == &list");
   if (!__c.empty()) {
-    __link_pointer __f = __c.__end_.__next_;
-    __link_pointer __l = __c.__end_.__prev_;
+    __base_pointer __f = __c.__end_.__next_;
+    __base_pointer __l = __c.__end_.__prev_;
     base::__unlink_nodes(__f, __l);
     __link_nodes(__p.__ptr_, __f, __l);
     base::__sz() += __c.__sz();
@@ -1444,7 +1442,7 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) {
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) {
   if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) {
-    __link_pointer __f = __i.__ptr_;
+    __base_pointer __f = __i.__ptr_;
     base::__unlink_nodes(__f, __f);
     __link_nodes(__p.__ptr_, __f, __f);
     --__c.__sz();
@@ -1455,9 +1453,9 @@ void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i
 template <class _Tp, class _Alloc>
 void list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) {
   if (__f != __l) {
-    __link_pointer __first = __f.__ptr_;
+    __base_pointer __first = __f.__ptr_;
     --__l;
-    __link_pointer __last = __l.__ptr_;
+    __base_pointer __last = __l.__ptr_;
     if (this != std::addressof(__c)) {
       size_type __s = std::distance(__f, __l) + 1;
       __c.__sz() -= __s;
@@ -1545,8 +1543,8 @@ void list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) {
           ;
         base::__sz() += __ds;
         __c.__sz() -= __ds;
-        __link_pointer __f = __f2.__ptr_;
-        __link_pointer __l = __m2.__ptr_->__prev_;
+        __base_pointer __f = __f2.__ptr_;
+        __base_pointer __l = __m2.__ptr_->__prev_;
         __f2               = __m2;
         base::__unlink_nodes(__f, __l);
         __m2 = std::next(__f1);
@@ -1580,7 +1578,7 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __
     return __f1;
   case 2:
     if (__comp(*--__e2, *__f1)) {
-      __link_pointer __f = __e2.__ptr_;
+      __base_pointer __f = __e2.__ptr_;
       base::__unlink_nodes(__f, __f);
       __link_nodes(__f1.__ptr_, __f, __f);
       return __e2;
@@ -1595,8 +1593,8 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __
     iterator __m2 = std::next(__f2);
     for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
       ;
-    __link_pointer __f = __f2.__ptr_;
-    __link_pointer __l = __m2.__ptr_->__prev_;
+    __base_pointer __f = __f2.__ptr_;
+    __base_pointer __l = __m2.__ptr_->__prev_;
     __r                = __f2;
     __e1 = __f2 = __m2;
     base::__unlink_nodes(__f, __l);
@@ -1610,8 +1608,8 @@ list<_Tp, _Alloc>::__sort(iterator __f1, iterator __e2, size_type __n, _Comp& __
       iterator __m2 = std::next(__f2);
       for (; __m2 != __e2 && __comp(*__m2, *__f1); ++__m2)
         ;
-      __link_pointer __f = __f2.__ptr_;
-      __link_pointer __l = __m2.__ptr_->__prev_;
+      __base_pointer __f = __f2.__ptr_;
+      __base_pointer __l = __m2.__ptr_->__prev_;
       if (__e1 == __f2)
         __e1 = __m2;
       __f2 = __m2;



More information about the libcxx-commits mailing list