[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
Mon Aug 18 04:19:04 PDT 2025


================
@@ -572,7 +574,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;
----------------
vinay-deshmukh wrote:

I believe the reason I had to add these was because I got errors like these:

Case 1):

Both 577 and 578 commented

<details>

<summary>

failures
</summary>

```
# .---command stderr------------
# | In file included from /source-dir/libcxx/test/std/containers/associative/map/compare.pass.cpp:18:
# | In file included from /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/map:599:
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:611:34: error: constructor for 'std::__tree_node<std::__value_type<Key, int>, void *>' must explicitly initialize the base class '__tree_node_base<void *>' which does not have a default constructor
# |   611 |   _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
# |       |                                  ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__memory/construct_at.h:38:49: note: in instantiation of function template specialization 'std::__tree_node<std::__value_type<Key, int>, void *>::__tree_node<std::allocator<std::__tree_node<std::__value_type<Key, int>, void *>>, const std::piecewise_construct_t &, std::tuple<Key &&>, std::tuple<>>' requested here
# |    38 |   return ::new (static_cast<void*>(__location)) _Tp(std::forward<_Args>(__args)...);
# |       |                                                 ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:1812:25: note: in instantiation of function template specialization 'std::__tree<std::__value_type<Key, int>, std::__map_value_compare<Key, std::pair<const Key, int>, std::less<Key>>, std::allocator<std::pair<const Key, int>>>::__construct_node<const std::piecewise_construct_t &, std::tuple<Key &&>, std::tuple<>>' requested here
# |  1812 |     __node_holder __h = __construct_node(std::forward<_Args>(__args)...);
# |       |                         ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/map:1410:8: note: in instantiation of function template specialization 'std::__tree<std::__value_type<Key, int>, std::__map_value_compare<Key, std::pair<const Key, int>, std::less<Key>>, std::allocator<std::pair<const Key, int>>>::__emplace_unique_key_args<Key, const std::piecewise_construct_t &, std::tuple<Key &&>, std::tuple<>>' requested here
# |  1410 |       .__emplace_unique_key_args(
# |       |        ^
# | /source-dir/libcxx/test/std/containers/associative/map/compare.pass.cpp:37:15: note: in instantiation of member function 'std::map<Key, int>::operator[]' requested here
# |    37 |     m_contains[Key(0)] = 42;
# |       |               ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:564:1: note: 'std::__tree_node_base<void *>' declared here
# |   564 | __tree_node_base : public __tree_end_node<__rebind_pointer_t<_VoidPtr, __tree_node_base<_VoidPtr> > > {
# |       | ^                                  ^
```

</details>

>From 43/64 `/map` tests

Case 2): Only 578 commented, (maybe a default destructortor is created)

all pass

case 3): `constructor() = default;` and `destructor = delete`

<details>

<summary>
failures
</summary>


```
# | In file included from /source-dir/libcxx/test/std/containers/associative/map/map.cons/copy_assign.addressof.compile.pass.cpp:17:
# | In file included from /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/map:599:
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:612:34: error: attempt to use a deleted function
# |   612 |   _LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
# |       |                                  ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__memory/construct_at.h:38:49: note: in instantiation of function template specialization 'std::__tree_node<std::__value_type<int, operator_hijacker>, void *>::__tree_node<std::allocator<std::__tree_node<std::__value_type<int, operator_hijacker>, void *>>, std::pair<const int, operator_hijacker> &>' requested here
# |    38 |   return ::new (static_cast<void*>(__location)) _Tp(std::forward<_Args>(__args)...);
# |       |                                                 ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:1283:32: note: in instantiation of function template specialization 'std::__tree<std::__value_type<int, operator_hijacker>, std::__map_value_compare<int, std::pair<const int, operator_hijacker>, std::less<int>>, std::allocator<std::pair<const int, operator_hijacker>>>::__construct_node<std::pair<const int, operator_hijacker> &>' requested here
# |  1283 |     __node_holder __new_node = __construct_node(__src->__get_value());
# |       |                                ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:1414:54: note: in instantiation of member function 'std::__tree<std::__value_type<int, operator_hijacker>, std::__map_value_compare<int, std::pair<const int, operator_hijacker>, std::less<int>>, std::allocator<std::pair<const int, operator_hijacker>>>::__copy_construct_tree' requested here
# |  1414 |     *__root_ptr() = static_cast<__node_base_pointer>(__copy_construct_tree(__t.__root()));
# |       |                                                      ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/map:977:64: note: in instantiation of member function 'std::__tree<std::__value_type<int, operator_hijacker>, std::__map_value_compare<int, std::pair<const int, operator_hijacker>, std::less<int>>, std::allocator<std::pair<const int, operator_hijacker>>>::operator=' requested here
# |   977 |   _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) = default;
# |       |                                                                ^
# | /source-dir/build/myclang22/libcxx/test-suite-install/include/c++/v1/__tree:579:3: note: '~__tree_node_base' has been explicitly marked deleted here
# |   579 |   ~__tree_node_base()                                  = delete;
|         ^~~~~~~~~~
```

</details?




https://github.com/llvm/llvm-project/pull/153908


More information about the libcxx-commits mailing list