-
Notifications
You must be signed in to change notification settings - Fork 15k
[libc++] Remove UB from std::map
by updating std::__tree_node
construction
#153908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[libc++] Remove UB from std::map
by updating std::__tree_node
construction
#153908
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
@@ -1808,7 +1842,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)...); |
There was a problem hiding this comment.
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
)
my bad, false alarm I do get test failures if I don't update set and multiset... |
… for UB removal (#154225) Prepare for: llvm/llvm-project#153908 (comment)
…roject into vinay-issue-128660-map-ub
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with the last two open comments addressed.
std::map
by updating std::__tree_node
construction / Update std::__hash_node
construction
std::map
by updating std::__tree_node
construction / Update std::__hash_node
constructionstd::map
by updating std::__tree_node
construction
libcxx/include/__hash_table
Outdated
// | ||
// 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)...); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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..
: _Base(__next), __hash_(__hash) { | ||
allocator_traits<_Alloc>::construct(__na, std::addressof(__get_value()), std::forward<_Args>(__args)...); | ||
} | ||
|
||
_LIBCPP_HIDE_FROM_ABI ~__hash_node() {} |
There was a problem hiding this comment.
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)
This patch also updates
__hash_table
to match what we do in__tree
now.Fixes #134330 (comment)