Skip to content
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2f689f9
use allocator as template arg and allocator_traits, tests passed in c…
vinay-deshmukh Aug 13, 2025
bbc637a
remove UB using list
vinay-deshmukh Aug 16, 2025
99c2829
cf
vinay-deshmukh Aug 16, 2025
5afe3a4
doc-fix
vinay-deshmukh Aug 16, 2025
ca72744
Replace __value_ with __get_value() for __tree_node
vinay-deshmukh Aug 16, 2025
47b71f8
miss typo
vinay-deshmukh Aug 16, 2025
d16fabf
fix ctor for cpp03 buffer
vinay-deshmukh Aug 16, 2025
dcd4cb4
cf
vinay-deshmukh Aug 16, 2025
08f5328
rename in map as well
vinay-deshmukh Aug 16, 2025
4b5609c
cf
vinay-deshmukh Aug 16, 2025
d24dbc2
include
vinay-deshmukh Aug 16, 2025
9c47574
more?
vinay-deshmukh Aug 16, 2025
8b1278e
hide from abi
vinay-deshmukh Aug 16, 2025
b241636
terser
vinay-deshmukh Aug 17, 2025
f5cc9c3
redundant launder
vinay-deshmukh Aug 18, 2025
c1a776e
single branch
vinay-deshmukh Aug 18, 2025
4e905fe
remove the & from buffer
vinay-deshmukh Aug 18, 2025
225b03c
remove _LIBCPP_STANDALONE_DEBUG
vinay-deshmukh Aug 18, 2025
1b01b80
cf
vinay-deshmukh Aug 18, 2025
62df872
Merge remote-tracking branch 'upstream/main' into vinay-issue-128660-…
vinay-deshmukh Aug 19, 2025
e035df9
Merge branch 'main' into vinay-issue-128660-map-ub
vinay-deshmukh Aug 30, 2025
675a0ca
Merge remote-tracking branch 'upstream/main' into vinay-issue-128660-…
vinay-deshmukh Aug 31, 2025
54951dd
Merge branch 'vinay-issue-128660-map-ub' of out:vinay-deshmukh/llvm-p…
vinay-deshmukh Aug 31, 2025
77c1569
Remove ~__tree_node_base() = default;
vinay-deshmukh Sep 1, 2025
0698243
Update __hash_node constructor to be similar to __tree_node
vinay-deshmukh Sep 1, 2025
5cd0195
cf
vinay-deshmukh Sep 1, 2025
881284a
Merge remote-tracking branch 'upstream/main' into vinay-issue-128660-…
vinay-deshmukh Sep 1, 2025
f7332e6
delete ~__tree_node_base
vinay-deshmukh Sep 4, 2025
8e9153e
Revert "delete ~__tree_node_base"
vinay-deshmukh Sep 4, 2025
3ded535
Default to nullptr, and assign __hash during construction
vinay-deshmukh Sep 6, 2025
ccc9292
fix eager reduction...
vinay-deshmukh Sep 7, 2025
a59fb89
format
vinay-deshmukh Sep 7, 2025
117e150
Fix doc comment, to say construct, not allocate
vinay-deshmukh Sep 7, 2025
f0dfc29
After public
vinay-deshmukh Sep 10, 2025
603b60b
Merge remote-tracking branch 'upstream/main' into vinay-issue-128660-…
vinay-deshmukh Sep 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 10 additions & 8 deletions libcxx/include/__hash_table
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,12 @@ public:
}
#endif

_LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {}
template <class _Alloc, class... _Args>
_LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash, _Alloc& __na, _Args&&... __args)
: _Base(__next), __hash_(__hash) {
allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
}

_LIBCPP_HIDE_FROM_ABI ~__hash_node() {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be changed to = default; as well? (while I'm changing this code)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A defaulted definition is possibly deleted because __node_value_type can be non-trivially destructible. I haven't check whether there's any code destroying the __hash_node as a whole (i.e. calling the destructor). If so, we shouldn't default it.

};

Expand Down Expand Up @@ -1874,16 +1879,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
__node_allocator& __na = __node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));

// Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value
// held inside the node, since we need to use the allocator's construct() method for that.
// Begin the lifetime of the node itself and the value_type contained within.
//
// We don't use the allocator's construct() method to construct the node itself since the
// Cpp17FooInsertable named requirements don't require the allocator's construct() method
// to work on anything other than the value_type.
std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0);
std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0, __na, std::forward<_Args>(__args)...);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we ever construct the node with anything but nullptr and 0? If not, I'd just move that into the constructor.

Copy link
Contributor Author

@vinay-deshmukh vinay-deshmukh Sep 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nullptr was used in all instances, but the hash = arg can be 0 or a variable for the second occurrence, so that is still a constructor arg.

one more thing, for the second instance this was 0, but then in the next line, it was being reassigned with a variable, so I changed that to be assigned through the constructor arg.

Update: as it needs to be computed after the __value_ is inititalized, we can't put that as a constructor arg unless we also send in the hash_function as a constructor arg..


// Now construct the value_type using the allocator's construct() method.
__node_traits::construct(__na, std::addressof(__h->__get_value()), std::forward<_Args>(__args)...);
__h.get_deleter().__value_constructed = true;

__h->__hash_ = hash_function()(__h->__get_value());
Expand All @@ -1897,8 +1899,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _
static_assert(!__is_hash_value_type<_Args...>::value, "Construct cannot be called with a hash value type");
__node_allocator& __na = __node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash);
__node_traits::construct(__na, std::addressof(__h->__get_value()), std::forward<_Args>(__args)...);
std::__construct_at(
std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash, __na, std::forward<_Args>(__args)...);
__h.get_deleter().__value_constructed = true;
return __h;
}
Expand Down
31 changes: 25 additions & 6 deletions libcxx/include/__tree
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@
#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>
#include <__new/launder.h>
#include <__type_traits/copy_cvref.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/invoke.h>
Expand Down Expand Up @@ -558,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> >;
Expand All @@ -572,22 +573,40 @@ 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;
__tree_node_base(__tree_node_base const&) = delete;
__tree_node_base& operator=(__tree_node_base const&) = delete;
};

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>;

// 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:
__node_value_type __value_;
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)];

public:
_LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return *reinterpret_cast<__node_value_type*>(__buffer_); }
#endif

template <class _Alloc, class... _Args>
_LIBCPP_HIDE_FROM_ABI explicit __tree_node(_Alloc& __na, _Args&&... __args) {
allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...);
}
~__tree_node() = delete;
__tree_node(__tree_node const&) = delete;
__tree_node& operator=(__tree_node const&) = delete;
Expand Down Expand Up @@ -1793,7 +1812,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->__get_value()), std::forward<_Args>(__args)...);
std::__construct_at(std::addressof(*__h), __na, std::forward<_Args>(__args)...);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N.B. This is the line that prompts this change due to needing workarounds when implementing P3372 for map (Add constexpr)

__h.get_deleter().__value_constructed = true;
return __h;
}
Expand Down
Loading