[libcxx-commits] [libcxx] [libc++] Remove UB from std::map __tree_node construction (PR #153908)

Vinay Deshmukh via libcxx-commits libcxx-commits at lists.llvm.org
Tue Aug 19 02:36:03 PDT 2025


https://github.com/vinay-deshmukh updated https://github.com/llvm/llvm-project/pull/153908

>From 2f689f97b6c729f03f37e51c941c32186e9d3565 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Wed, 13 Aug 2025 06:49:44 -0400
Subject: [PATCH 01/19] use allocator as template arg and allocator_traits,
 tests passed in cpp26

---
 libcxx/include/__tree | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index d154ce1616b93..3fef3efcf78a7 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -582,10 +582,16 @@ class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
 public:
   using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
 
+  union {
   __node_value_type __value_;
+  };
 
   _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
 
+  template <class _Alloc, class... _Args>
+  explicit __tree_node(_Alloc& __na, _Args&&... __args) {
+    allocator_traits<_Alloc>::construct(__na, std::addressof(__value_), std::forward<_Args>(__args)...);
+  }
   ~__tree_node()                             = delete;
   __tree_node(__tree_node const&)            = delete;
   __tree_node& operator=(__tree_node const&) = delete;
@@ -1808,7 +1814,7 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_holder
 __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
   __node_allocator& __na = __node_alloc();
   __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-  __node_traits::construct(__na, std::addressof(__h->__value_), std::forward<_Args>(__args)...);
+  std::__construct_at(std::addressof(*__h), __na, std::forward<_Args>(__args)...);
   __h.get_deleter().__value_constructed = true;
   return __h;
 }

>From bbc637ad50a0051e1f46da96bdbef6205e7f846d Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 20:46:20 -0400
Subject: [PATCH 02/19] remove UB using list

---
 libcxx/include/__tree | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 3fef3efcf78a7..d860f4c96f467 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -582,11 +582,25 @@ class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
 public:
   using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
 
-  union {
-  __node_value_type __value_;
-  };
+  // We allow starting the lifetime of nodes without initializing the value held by the node,
+  // since that is handled by the map itself in order to be allocator-aware.
+  #  ifndef _LIBCPP_CXX03_LANG
+
+  private:
+    union {
+      __node_value_type __value_;
+    };
+
+  public:
+    _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
+  #  else
+
+  private:
+    _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
 
-  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
+  public:
+    _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
+  #  endif
 
   template <class _Alloc, class... _Args>
   explicit __tree_node(_Alloc& __na, _Args&&... __args) {

>From 99c2829166a093ac57479a0b8cb7fbed806cf00c Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 20:53:57 -0400
Subject: [PATCH 03/19] cf

---
 libcxx/include/__tree | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index d860f4c96f467..5245dcdb23434 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -582,25 +582,25 @@ class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
 public:
   using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
 
-  // We allow starting the lifetime of nodes without initializing the value held by the node,
-  // since that is handled by the map itself in order to be allocator-aware.
-  #  ifndef _LIBCPP_CXX03_LANG
+// We allow starting the lifetime of nodes without initializing the value held by the node,
+// since that is handled by the map itself in order to be allocator-aware.
+#ifndef _LIBCPP_CXX03_LANG
 
-  private:
-    union {
-      __node_value_type __value_;
-    };
+private:
+  union {
+    __node_value_type __value_;
+  };
 
-  public:
-    _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
-  #  else
+public:
+  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
+#else
 
-  private:
-    _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
+private:
+  _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
 
-  public:
-    _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
-  #  endif
+public:
+  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
+#endif
 
   template <class _Alloc, class... _Args>
   explicit __tree_node(_Alloc& __na, _Args&&... __args) {

>From 5afe3a4b2ca319491fe05e57e6a46eae4add233b Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 20:54:06 -0400
Subject: [PATCH 04/19] doc-fix

---
 libcxx/include/__tree | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 5245dcdb23434..e1da5e65e3cde 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -582,8 +582,8 @@ class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
 public:
   using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
 
-// We allow starting the lifetime of nodes without initializing the value held by the node,
-// since that is handled by the map itself in order to be allocator-aware.
+// We use a union to avoid initialization during member initialization, which allows us
+// to use the allocator from the container to allocate the node itself
 #ifndef _LIBCPP_CXX03_LANG
 
 private:

>From ca7274486aedc1f13764e5ab88bd0962babc9eb9 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:03:36 -0400
Subject: [PATCH 05/19] Replace __value_ with __get_value() for __tree_node

---
 libcxx/include/__tree | 91 ++++++++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 45 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index e1da5e65e3cde..3fb4769f9bed6 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -572,7 +572,8 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__end_node_pointer>(__p); }
 
-  ~__tree_node_base()                                  = delete;
+  _LIBCPP_HIDE_FROM_ABI __tree_node_base() = default;
+  _LIBCPP_HIDE_FROM_ABI ~__tree_node_base()                                  = default;
   __tree_node_base(__tree_node_base const&)            = delete;
   __tree_node_base& operator=(__tree_node_base const&) = delete;
 };
@@ -634,7 +635,7 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
     if (__value_constructed)
-      __alloc_traits::destroy(__na_, std::addressof(__p->__value_));
+      __alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
     if (__p)
       __alloc_traits::deallocate(__na_, __p, 1);
   }
@@ -670,8 +671,8 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
 
-  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
-  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
+  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
+  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__get_value()); }
 
   _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() {
     __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
@@ -732,8 +733,8 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
 
-  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__value_; }
-  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__value_); }
+  _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
+  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__get_value()); }
 
   _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() {
     __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
@@ -1246,7 +1247,7 @@ private:
 
       auto __right = __ptr->__right_;
 
-      __node_traits::destroy(__alloc_, std::addressof(__ptr->__value_));
+      __node_traits::destroy(__alloc_, std::addressof(__ptr->__get_value()));
       __node_traits::deallocate(__alloc_, __ptr, 1);
 
       (*this)(static_cast<__node_pointer>(__right));
@@ -1265,7 +1266,7 @@ private:
     if (!__src)
       return nullptr;
 
-    __node_holder __new_node = __construct_node(__src->__value_);
+    __node_holder __new_node = __construct_node(__src->__get_value());
 
     unique_ptr<__node, __tree_deleter> __left(
         __copy_construct_tree(static_cast<__node_pointer>(__src->__left_)), __node_alloc_);
@@ -1296,7 +1297,7 @@ private:
       return nullptr;
     }
 
-    __assign_value(__dest->__value_, __src->__value_);
+    __assign_value(__dest->__get_value(), __src->__get_value());
     __dest->__is_black_ = __src->__is_black_;
 
     // If we already have a left node in the destination tree, reuse it and copy-assign recursively
@@ -1437,7 +1438,7 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _
   if (__size_ != 0) {
     _DetachedTreeCache __cache(this);
     for (; __cache.__get() && __first != __last; ++__first) {
-      __assign_value(__cache.__get()->__value_, *__first);
+      __assign_value(__cache.__get()->__get_value(), *__first);
       __node_insert_multi(__cache.__get());
       __cache.__advance();
     }
@@ -1529,13 +1530,13 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
     if (__size_ != 0) {
       _DetachedTreeCache __cache(this);
       while (__cache.__get() != nullptr && __t.__size_ != 0) {
-        __assign_value(__cache.__get()->__value_, std::move(__t.remove(__t.begin())->__value_));
+        __assign_value(__cache.__get()->__get_value(), std::move(__t.remove(__t.begin())->__get_value()));
         __node_insert_multi(__cache.__get());
         __cache.__advance();
       }
     }
     while (__t.__size_ != 0) {
-      __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__value_));
+      __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__get_value()));
     }
   }
 }
@@ -1603,7 +1604,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__end_node_pointer& __parent,
   __node_pointer __nd = __root();
   if (__nd != nullptr) {
     while (true) {
-      if (value_comp()(__nd->__value_, __v)) {
+      if (value_comp()(__nd->__get_value(), __v)) {
         if (__nd->__right_ != nullptr)
           __nd = static_cast<__node_pointer>(__nd->__right_);
         else {
@@ -1633,7 +1634,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__end_node_pointer& __parent
   __node_pointer __nd = __root();
   if (__nd != nullptr) {
     while (true) {
-      if (value_comp()(__v, __nd->__value_)) {
+      if (value_comp()(__v, __nd->__get_value())) {
         if (__nd->__left_ != nullptr)
           __nd = static_cast<__node_pointer>(__nd->__left_);
         else {
@@ -1696,7 +1697,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, co
   __node_base_pointer* __nd_ptr = __root_ptr();
   if (__nd != nullptr) {
     while (true) {
-      if (value_comp()(__v, __nd->__value_)) {
+      if (value_comp()(__v, __nd->__get_value())) {
         if (__nd->__left_ != nullptr) {
           __nd_ptr = std::addressof(__nd->__left_);
           __nd     = static_cast<__node_pointer>(__nd->__left_);
@@ -1704,7 +1705,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, co
           __parent = static_cast<__end_node_pointer>(__nd);
           return __parent->__left_;
         }
-      } else if (value_comp()(__nd->__value_, __v)) {
+      } else if (value_comp()(__nd->__get_value(), __v)) {
         if (__nd->__right_ != nullptr) {
           __nd_ptr = std::addressof(__nd->__right_);
           __nd     = static_cast<__node_pointer>(__nd->__right_);
@@ -1839,7 +1840,7 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
 __tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) {
   __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
+  __node_base_pointer& __child = __find_equal(__parent, __h->__get_value());
   __node_pointer __r           = static_cast<__node_pointer>(__child);
   bool __inserted              = false;
   if (__child == nullptr) {
@@ -1857,7 +1858,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p
   __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
   __end_node_pointer __parent;
   __node_base_pointer __dummy;
-  __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_);
+  __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__get_value());
   __node_pointer __r           = static_cast<__node_pointer>(__child);
   if (__child == nullptr) {
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
@@ -1872,7 +1873,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) {
   __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_);
+  __node_base_pointer& __child = __find_leaf_high(__parent, __h->__get_value());
   __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
   return iterator(static_cast<__node_pointer>(__h.release()));
 }
@@ -1883,7 +1884,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) {
   __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_);
+  __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__get_value());
   __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
   return iterator(static_cast<__node_pointer>(__h.release()));
 }
@@ -1896,7 +1897,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, _
   __node_pointer __r           = static_cast<__node_pointer>(__child);
   bool __inserted              = false;
   if (__child == nullptr) {
-    __assign_value(__nd->__value_, __v);
+    __assign_value(__nd->__get_value(), __v);
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
     __r        = __nd;
     __inserted = true;
@@ -1908,7 +1909,7 @@ template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) {
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_);
+  __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__get_value());
   __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
   return iterator(__nd);
 }
@@ -1917,7 +1918,7 @@ template <class _Tp, class _Compare, class _Allocator>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) {
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_);
+  __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__get_value());
   __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
   return iterator(__nd);
 }
@@ -1944,7 +1945,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
 
   __node_pointer __ptr = __nh.__ptr_;
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_equal(__parent, __ptr->__value_);
+  __node_base_pointer& __child = __find_equal(__parent, __ptr->__get_value());
   if (__child != nullptr)
     return _InsertReturnType{iterator(static_cast<__node_pointer>(__child)), false, std::move(__nh)};
 
@@ -1963,7 +1964,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
   __node_pointer __ptr = __nh.__ptr_;
   __end_node_pointer __parent;
   __node_base_pointer __dummy;
-  __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, __ptr->__value_);
+  __node_base_pointer& __child = __find_equal(__hint, __parent, __dummy, __ptr->__get_value());
   __node_pointer __r           = static_cast<__node_pointer>(__child);
   if (__child == nullptr) {
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
@@ -1998,7 +1999,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merg
   for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
     __node_pointer __src_ptr = __i.__get_np();
     __end_node_pointer __parent;
-    __node_base_pointer& __child = __find_equal(__parent, __src_ptr->__value_);
+    __node_base_pointer& __child = __find_equal(__parent, __src_ptr->__get_value());
     ++__i;
     if (__child != nullptr)
       continue;
@@ -2015,7 +2016,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(_NodeHandle&& __nh
     return end();
   __node_pointer __ptr = __nh.__ptr_;
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__value_);
+  __node_base_pointer& __child = __find_leaf_high(__parent, __ptr->__get_value());
   __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
   __nh.__release_ptr();
   return iterator(__ptr);
@@ -2030,7 +2031,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi(const_iterator __h
 
   __node_pointer __ptr = __nh.__ptr_;
   __end_node_pointer __parent;
-  __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__value_);
+  __node_base_pointer& __child = __find_leaf(__hint, __parent, __ptr->__get_value());
   __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__ptr));
   __nh.__release_ptr();
   return iterator(__ptr);
@@ -2044,7 +2045,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merg
   for (typename _Tree::iterator __i = __source.begin(); __i != __source.end();) {
     __node_pointer __src_ptr = __i.__get_np();
     __end_node_pointer __parent;
-    __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__value_);
+    __node_base_pointer& __child = __find_leaf_high(__parent, __src_ptr->__get_value());
     ++__i;
     __source.__remove_node_pointer(__src_ptr);
     __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__src_ptr));
@@ -2099,9 +2100,9 @@ typename __tree<_Tp, _Compare, _Allocator>::size_type
 __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const {
   __node_pointer __rt = __root();
   while (__rt != nullptr) {
-    if (value_comp()(__k, __rt->__value_)) {
+    if (value_comp()(__k, __rt->__get_value())) {
       __rt = static_cast<__node_pointer>(__rt->__left_);
-    } else if (value_comp()(__rt->__value_, __k))
+    } else if (value_comp()(__rt->__get_value(), __k))
       __rt = static_cast<__node_pointer>(__rt->__right_);
     else
       return 1;
@@ -2116,10 +2117,10 @@ __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const {
   __end_node_pointer __result = __end_node();
   __node_pointer __rt         = __root();
   while (__rt != nullptr) {
-    if (value_comp()(__k, __rt->__value_)) {
+    if (value_comp()(__k, __rt->__get_value())) {
       __result = static_cast<__end_node_pointer>(__rt);
       __rt     = static_cast<__node_pointer>(__rt->__left_);
-    } else if (value_comp()(__rt->__value_, __k))
+    } else if (value_comp()(__rt->__get_value(), __k))
       __rt = static_cast<__node_pointer>(__rt->__right_);
     else
       return std::distance(
@@ -2134,7 +2135,7 @@ template <class _Key>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
   while (__root != nullptr) {
-    if (!value_comp()(__root->__value_, __v)) {
+    if (!value_comp()(__root->__get_value(), __v)) {
       __result = static_cast<__end_node_pointer>(__root);
       __root   = static_cast<__node_pointer>(__root->__left_);
     } else
@@ -2148,7 +2149,7 @@ template <class _Key>
 typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(
     const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
   while (__root != nullptr) {
-    if (!value_comp()(__root->__value_, __v)) {
+    if (!value_comp()(__root->__get_value(), __v)) {
       __result = static_cast<__end_node_pointer>(__root);
       __root   = static_cast<__node_pointer>(__root->__left_);
     } else
@@ -2162,7 +2163,7 @@ template <class _Key>
 typename __tree<_Tp, _Compare, _Allocator>::iterator
 __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, __end_node_pointer __result) {
   while (__root != nullptr) {
-    if (value_comp()(__v, __root->__value_)) {
+    if (value_comp()(__v, __root->__get_value())) {
       __result = static_cast<__end_node_pointer>(__root);
       __root   = static_cast<__node_pointer>(__root->__left_);
     } else
@@ -2176,7 +2177,7 @@ template <class _Key>
 typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(
     const _Key& __v, __node_pointer __root, __end_node_pointer __result) const {
   while (__root != nullptr) {
-    if (value_comp()(__v, __root->__value_)) {
+    if (value_comp()(__v, __root->__get_value())) {
       __result = static_cast<__end_node_pointer>(__root);
       __root   = static_cast<__node_pointer>(__root->__left_);
     } else
@@ -2193,10 +2194,10 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) {
   __end_node_pointer __result = __end_node();
   __node_pointer __rt         = __root();
   while (__rt != nullptr) {
-    if (value_comp()(__k, __rt->__value_)) {
+    if (value_comp()(__k, __rt->__get_value())) {
       __result = static_cast<__end_node_pointer>(__rt);
       __rt     = static_cast<__node_pointer>(__rt->__left_);
-    } else if (value_comp()(__rt->__value_, __k))
+    } else if (value_comp()(__rt->__get_value(), __k))
       __rt = static_cast<__node_pointer>(__rt->__right_);
     else
       return _Pp(iterator(__rt),
@@ -2215,10 +2216,10 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const {
   __end_node_pointer __result = __end_node();
   __node_pointer __rt         = __root();
   while (__rt != nullptr) {
-    if (value_comp()(__k, __rt->__value_)) {
+    if (value_comp()(__k, __rt->__get_value())) {
       __result = static_cast<__end_node_pointer>(__rt);
       __rt     = static_cast<__node_pointer>(__rt->__left_);
-    } else if (value_comp()(__rt->__value_, __k))
+    } else if (value_comp()(__rt->__get_value(), __k))
       __rt = static_cast<__node_pointer>(__rt->__right_);
     else
       return _Pp(
@@ -2237,10 +2238,10 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) {
   __end_node_pointer __result = __end_node();
   __node_pointer __rt     = __root();
   while (__rt != nullptr) {
-    if (value_comp()(__k, __rt->__value_)) {
+    if (value_comp()(__k, __rt->__get_value())) {
       __result = static_cast<__end_node_pointer>(__rt);
       __rt     = static_cast<__node_pointer>(__rt->__left_);
-    } else if (value_comp()(__rt->__value_, __k))
+    } else if (value_comp()(__rt->__get_value(), __k))
       __rt = static_cast<__node_pointer>(__rt->__right_);
     else
       return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),
@@ -2258,10 +2259,10 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const {
   __end_node_pointer __result = __end_node();
   __node_pointer __rt     = __root();
   while (__rt != nullptr) {
-    if (value_comp()(__k, __rt->__value_)) {
+    if (value_comp()(__k, __rt->__get_value())) {
       __result = static_cast<__end_node_pointer>(__rt);
       __rt     = static_cast<__node_pointer>(__rt->__left_);
-    } else if (value_comp()(__rt->__value_, __k))
+    } else if (value_comp()(__rt->__get_value(), __k))
       __rt = static_cast<__node_pointer>(__rt->__right_);
     else
       return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__end_node_pointer>(__rt)),

>From 47b71f8220c5f6c64d126c427cdd94cbaff68af3 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:06:19 -0400
Subject: [PATCH 06/19] miss typo

---
 libcxx/include/__tree | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 3fb4769f9bed6..32d609e7264b8 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -600,7 +600,7 @@ private:
   _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); }
+  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *std::__launder(reinterpret_cast<__node_value_type*>(&__buffer_)); }
 #endif
 
   template <class _Alloc, class... _Args>

>From d16fabf3ded283e3780d3c1c49f9411b5b3d4be2 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:09:59 -0400
Subject: [PATCH 07/19] fix ctor for cpp03 buffer

---
 libcxx/include/__tree | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 32d609e7264b8..d53e2ff1a0318 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -23,6 +23,7 @@
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>
+#include <__new/launder.h>
 #include <__type_traits/can_extract_key.h>
 #include <__type_traits/copy_cvref.h>
 #include <__type_traits/enable_if.h>
@@ -605,7 +606,12 @@ public:
 
   template <class _Alloc, class... _Args>
   explicit __tree_node(_Alloc& __na, _Args&&... __args) {
+
+#ifndef _LIBCPP_CXX03_LANG
     allocator_traits<_Alloc>::construct(__na, std::addressof(__value_), std::forward<_Args>(__args)...);
+#else
+    allocator_traits<_Alloc>::construct(__na, reinterpret_cast<__node_value_type*>(std::addressof(__buffer_)), std::forward<_Args>(__args)...);
+#endif
   }
   ~__tree_node()                             = delete;
   __tree_node(__tree_node const&)            = delete;

>From dcd4cb49bc98c0abb7d7596fbe185515c2fecbd3 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:13:25 -0400
Subject: [PATCH 08/19] cf

---
 libcxx/include/__tree | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index d53e2ff1a0318..ca4cfe202d419 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -573,8 +573,8 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __p) { __parent_ = static_cast<__end_node_pointer>(__p); }
 
-  _LIBCPP_HIDE_FROM_ABI __tree_node_base() = default;
-  _LIBCPP_HIDE_FROM_ABI ~__tree_node_base()                                  = default;
+  _LIBCPP_HIDE_FROM_ABI __tree_node_base()             = default;
+  _LIBCPP_HIDE_FROM_ABI ~__tree_node_base()            = default;
   __tree_node_base(__tree_node_base const&)            = delete;
   __tree_node_base& operator=(__tree_node_base const&) = delete;
 };
@@ -678,7 +678,9 @@ public:
   _LIBCPP_HIDE_FROM_ABI __tree_iterator() _NOEXCEPT : __ptr_(nullptr) {}
 
   _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
-  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__get_value()); }
+  _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
+    return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
+  }
 
   _LIBCPP_HIDE_FROM_ABI __tree_iterator& operator++() {
     __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));
@@ -740,7 +742,9 @@ public:
   _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
 
   _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __get_np()->__get_value(); }
-  _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__get_np()->__get_value()); }
+  _LIBCPP_HIDE_FROM_ABI pointer operator->() const {
+    return pointer_traits<pointer>::pointer_to(__get_np()->__get_value());
+  }
 
   _LIBCPP_HIDE_FROM_ABI __tree_const_iterator& operator++() {
     __ptr_ = std::__tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_));

>From 08f53284bd9cd4d8b44dc1e56ac5be518929342c Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:17:46 -0400
Subject: [PATCH 09/19] rename in map as well

---
 libcxx/include/map | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/map b/libcxx/include/map
index 9f98abef9afe0..df9597f999895 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -741,9 +741,9 @@ public:
 
   _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
     if (__second_constructed)
-      __alloc_traits::destroy(__na_, std::addressof(__p->__value_.second));
+      __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().second));
     if (__first_constructed)
-      __alloc_traits::destroy(__na_, std::addressof(__p->__value_.first));
+      __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().first));
     if (__p)
       __alloc_traits::deallocate(__na_, __p, 1);
   }
@@ -1389,7 +1389,7 @@ map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
   if (__a != __m.get_allocator()) {
     const_iterator __e = cend();
     while (!__m.empty()) {
-      __tree_.__insert_unique_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
+      __tree_.__insert_unique_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
     }
   }
 }
@@ -1419,9 +1419,9 @@ typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
 map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) {
   __node_allocator& __na = __tree_.__node_alloc();
   __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-  __node_traits::construct(__na, std::addressof(__h->__value_.first), __k);
+  __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k);
   __h.get_deleter().__first_constructed = true;
-  __node_traits::construct(__na, std::addressof(__h->__value_.second));
+  __node_traits::construct(__na, std::addressof(__h->__get_value().second));
   __h.get_deleter().__second_constructed = true;
   return __h;
 }
@@ -1436,7 +1436,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
     __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
     __r = __h.release();
   }
-  return __r->__value_.second;
+  return __r->__get_value().second;
 }
 
 #  endif // _LIBCPP_CXX03_LANG
@@ -1447,7 +1447,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {
   __node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
   if (__child == nullptr)
     std::__throw_out_of_range("map::at:  key not found");
-  return static_cast<__node_pointer>(__child)->__value_.second;
+  return static_cast<__node_pointer>(__child)->__get_value().second;
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
@@ -1456,7 +1456,7 @@ const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {
   __node_base_pointer __child = __tree_.__find_equal(__parent, __k);
   if (__child == nullptr)
     std::__throw_out_of_range("map::at:  key not found");
-  return static_cast<__node_pointer>(__child)->__value_.second;
+  return static_cast<__node_pointer>(__child)->__get_value().second;
 }
 
 template <class _Key, class _Tp, class _Compare, class _Allocator>
@@ -1959,7 +1959,7 @@ multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const alloca
   if (__a != __m.get_allocator()) {
     const_iterator __e = cend();
     while (!__m.empty())
-      __tree_.__insert_multi_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_));
+      __tree_.__insert_multi_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
   }
 }
 #  endif

>From 4b5609c580a5b113b3dc0d2e67b60b06573e7859 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:34:36 -0400
Subject: [PATCH 10/19] cf

---
 libcxx/include/__tree | 8 +++++---
 libcxx/include/map    | 6 ++++--
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index ca4cfe202d419..ae66a29f60f58 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -601,16 +601,18 @@ private:
   _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *std::__launder(reinterpret_cast<__node_value_type*>(&__buffer_)); }
+  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() {
+    return *std::__launder(reinterpret_cast<__node_value_type*>(&__buffer_));
+  }
 #endif
 
   template <class _Alloc, class... _Args>
   explicit __tree_node(_Alloc& __na, _Args&&... __args) {
-
 #ifndef _LIBCPP_CXX03_LANG
     allocator_traits<_Alloc>::construct(__na, std::addressof(__value_), std::forward<_Args>(__args)...);
 #else
-    allocator_traits<_Alloc>::construct(__na, reinterpret_cast<__node_value_type*>(std::addressof(__buffer_)), std::forward<_Args>(__args)...);
+    allocator_traits<_Alloc>::construct(
+        __na, reinterpret_cast<__node_value_type*>(std::addressof(__buffer_)), std::forward<_Args>(__args)...);
 #endif
   }
   ~__tree_node()                             = delete;
diff --git a/libcxx/include/map b/libcxx/include/map
index df9597f999895..4dfce70e50e7f 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -1389,7 +1389,8 @@ map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)
   if (__a != __m.get_allocator()) {
     const_iterator __e = cend();
     while (!__m.empty()) {
-      __tree_.__insert_unique_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
+      __tree_.__insert_unique_from_orphaned_node(
+          __e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
     }
   }
 }
@@ -1959,7 +1960,8 @@ multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const alloca
   if (__a != __m.get_allocator()) {
     const_iterator __e = cend();
     while (!__m.empty())
-      __tree_.__insert_multi_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
+      __tree_.__insert_multi_from_orphaned_node(
+          __e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__get_value()));
   }
 }
 #  endif

>From d24dbc2571939428a812031b506989decae0c826 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:35:28 -0400
Subject: [PATCH 11/19] include

---
 libcxx/include/__tree | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index ae66a29f60f58..81bc316486964 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -20,6 +20,7 @@
 #include <__memory/addressof.h>
 #include <__memory/allocator_traits.h>
 #include <__memory/compressed_pair.h>
+#include <__memory/construct_at.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>
 #include <__memory/unique_ptr.h>

>From 9c4757435b8c5d7e5521ede95817d993a35c3800 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Fri, 15 Aug 2025 21:49:59 -0400
Subject: [PATCH 12/19] more?

---
 libcxx/include/set | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/set b/libcxx/include/set
index c77345bc5dc1f..05c1939dbbabf 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -953,7 +953,7 @@ set<_Key, _Compare, _Allocator>::set(set&& __s, const allocator_type& __a) : __t
   if (__a != __s.get_allocator()) {
     const_iterator __e = cend();
     while (!__s.empty())
-      insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
+      insert(__e, std::move(__s.__tree_.remove(__s.begin())->__get_value()));
   }
 }
 
@@ -1416,7 +1416,7 @@ multiset<_Key, _Compare, _Allocator>::multiset(multiset&& __s, const allocator_t
   if (__a != __s.get_allocator()) {
     const_iterator __e = cend();
     while (!__s.empty())
-      insert(__e, std::move(__s.__tree_.remove(__s.begin())->__value_));
+      insert(__e, std::move(__s.__tree_.remove(__s.begin())->__get_value()));
   }
 }
 

>From 8b1278ea7c37c0d8bc3ac7694c8f75e13cffbb57 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Sat, 16 Aug 2025 09:13:18 -0400
Subject: [PATCH 13/19] hide from abi

---
 libcxx/include/__tree | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 81bc316486964..09a7da8943e20 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -608,7 +608,7 @@ public:
 #endif
 
   template <class _Alloc, class... _Args>
-  explicit __tree_node(_Alloc& __na, _Args&&... __args) {
+  _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
 #ifndef _LIBCPP_CXX03_LANG
     allocator_traits<_Alloc>::construct(__na, std::addressof(__value_), std::forward<_Args>(__args)...);
 #else

>From b2416366dbe2d55ee56dc991266131d6ce0d2966 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Sun, 17 Aug 2025 09:10:23 -0400
Subject: [PATCH 14/19] terser

---
 libcxx/include/__tree | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 09a7da8943e20..b379b1bb1e4aa 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -613,7 +613,7 @@ public:
     allocator_traits<_Alloc>::construct(__na, std::addressof(__value_), std::forward<_Args>(__args)...);
 #else
     allocator_traits<_Alloc>::construct(
-        __na, reinterpret_cast<__node_value_type*>(std::addressof(__buffer_)), std::forward<_Args>(__args)...);
+        __na, reinterpret_cast<__node_value_type*>(__buffer_), std::forward<_Args>(__args)...);
 #endif
   }
   ~__tree_node()                             = delete;

>From f5cc9c3c8cf47ff634fb2e356516e1e1018af097 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Mon, 18 Aug 2025 07:36:10 -0400
Subject: [PATCH 15/19] redundant launder

---
 libcxx/include/__tree | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index b379b1bb1e4aa..a0bcaf2408765 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -603,7 +603,7 @@ private:
 
 public:
   _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() {
-    return *std::__launder(reinterpret_cast<__node_value_type*>(&__buffer_));
+    return *reinterpret_cast<__node_value_type*>(&__buffer_);
   }
 #endif
 

>From c1a776e69dfe39fb593b707c327b6d73df58ccd7 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Mon, 18 Aug 2025 07:37:53 -0400
Subject: [PATCH 16/19] single branch

---
 libcxx/include/__tree | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index a0bcaf2408765..b2dd538c2ca6d 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -609,12 +609,7 @@ public:
 
   template <class _Alloc, class... _Args>
   _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
-#ifndef _LIBCPP_CXX03_LANG
-    allocator_traits<_Alloc>::construct(__na, std::addressof(__value_), std::forward<_Args>(__args)...);
-#else
-    allocator_traits<_Alloc>::construct(
-        __na, reinterpret_cast<__node_value_type*>(__buffer_), std::forward<_Args>(__args)...);
-#endif
+    allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
   }
   ~__tree_node()                             = delete;
   __tree_node(__tree_node const&)            = delete;

>From 4e905fecc62fc46649e570806fec8c572d8555ba Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Mon, 18 Aug 2025 19:24:38 -0400
Subject: [PATCH 17/19] remove the & from buffer

---
 libcxx/include/__tree | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index b2dd538c2ca6d..4cc4e1c905fa8 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -603,7 +603,7 @@ private:
 
 public:
   _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() {
-    return *reinterpret_cast<__node_value_type*>(&__buffer_);
+    return *reinterpret_cast<__node_value_type*>(__buffer_);
   }
 #endif
 

>From 225b03cf465124b67d9e84bef50dfa10d99270c1 Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Mon, 18 Aug 2025 19:51:44 -0400
Subject: [PATCH 18/19] remove _LIBCPP_STANDALONE_DEBUG

---
 libcxx/include/__config | 6 ------
 libcxx/include/__tree   | 5 ++---
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 77a71b6cf1cae..3b590277eaf3b 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1169,12 +1169,6 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_NO_SPECIALIZATIONS
 #  endif
 
-#  if __has_cpp_attribute(_Clang::__standalone_debug__)
-#    define _LIBCPP_STANDALONE_DEBUG [[_Clang::__standalone_debug__]]
-#  else
-#    define _LIBCPP_STANDALONE_DEBUG
-#  endif
-
 #  if __has_cpp_attribute(_Clang::__preferred_name__)
 #    define _LIBCPP_PREFERRED_NAME(x) [[_Clang::__preferred_name__(x)]]
 #  else
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 4cc4e1c905fa8..0edac54f4ae53 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -560,8 +560,7 @@ public:
 };
 
 template <class _VoidPtr>
-class _LIBCPP_STANDALONE_DEBUG
-__tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
+class __tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
 public:
   using pointer                            = __rebind_pointer_t<_VoidPtr, __tree_node_base>;
   using __end_node_pointer _LIBCPP_NODEBUG = __rebind_pointer_t<_VoidPtr, __tree_end_node<pointer> >;
@@ -581,7 +580,7 @@ public:
 };
 
 template <class _Tp, class _VoidPtr>
-class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
+class __tree_node : public __tree_node_base<_VoidPtr> {
 public:
   using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>;
 

>From 1b01b80d3eadab50f69c726315fa277ea26057ba Mon Sep 17 00:00:00 2001
From: Vinay Deshmukh <32487576+vinay-deshmukh at users.noreply.github.com>
Date: Mon, 18 Aug 2025 19:54:54 -0400
Subject: [PATCH 19/19] cf

---
 libcxx/include/__tree | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 0edac54f4ae53..1cb372bda9643 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -601,9 +601,7 @@ private:
   _ALIGNAS_TYPE(__node_value_type) unsigned char __buffer_[sizeof(__node_value_type)];
 
 public:
-  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() {
-    return *reinterpret_cast<__node_value_type*>(__buffer_);
-  }
+  _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *reinterpret_cast<__node_value_type*>(__buffer_); }
 #endif
 
   template <class _Alloc, class... _Args>



More information about the libcxx-commits mailing list