8373638: RBTree public interface does not check all input parameters for validity

Reviewed-by: ayang, dholmes
This commit is contained in:
Casper Norrbin 2026-02-20 10:56:15 +00:00
parent c3a698f7be
commit 16f2b80327

View File

@ -408,7 +408,9 @@ AbstractRBTree<K, NodeType, COMPARATOR>::cursor(const K& key, const NodeType* hi
template <typename K, typename NodeType, typename COMPARATOR>
inline void AbstractRBTree<K, NodeType, COMPARATOR>::insert_at_cursor(NodeType* node, const Cursor& node_cursor) {
assert(node_cursor.valid() && !node_cursor.found(), "must be");
precond(node != nullptr);
precond(node_cursor.valid());
precond(!node_cursor.found());
_num_nodes++;
*node_cursor._insert_location = node;
@ -622,7 +624,8 @@ inline void AbstractRBTree<K, NodeType, COMPARATOR>::remove_from_tree(IntrusiveR
template <typename K, typename NodeType, typename COMPARATOR>
inline void AbstractRBTree<K, NodeType, COMPARATOR>::remove_at_cursor(const Cursor& node_cursor) {
assert(node_cursor.valid() && node_cursor.found(), "must be");
precond(node_cursor.valid());
precond(node_cursor.found());
_num_nodes--;
IntrusiveRBNode* node = node_cursor.node();
@ -718,7 +721,9 @@ AbstractRBTree<K, NodeType, COMPARATOR>::prev(const Cursor& node_cursor) const {
template <typename K, typename NodeType, typename COMPARATOR>
inline void AbstractRBTree<K, NodeType, COMPARATOR>::replace_at_cursor(NodeType* new_node, const Cursor& node_cursor) {
assert(node_cursor.valid() && node_cursor.found(), "must be");
precond(new_node != nullptr);
precond(node_cursor.valid());
precond(node_cursor.found());
NodeType* old_node = node_cursor.node();
if (old_node == new_node) {
return;
@ -785,12 +790,14 @@ inline NodeType* AbstractRBTree<K, NodeType, COMPARATOR>::find_node(const K& key
template <typename K, typename NodeType, typename COMPARATOR>
inline void AbstractRBTree<K, NodeType, COMPARATOR>::insert(const K& key, NodeType* node, const NodeType* hint_node) {
precond(node != nullptr);
Cursor node_cursor = cursor(key, hint_node);
insert_at_cursor(node, node_cursor);
}
template <typename K, typename NodeType, typename COMPARATOR>
inline void AbstractRBTree<K, NodeType, COMPARATOR>::remove(NodeType* node) {
precond(node != nullptr);
Cursor node_cursor = cursor(node);
remove_at_cursor(node_cursor);
}
@ -1049,9 +1056,9 @@ inline RBTree<K, V, COMPARATOR, ALLOCATOR>::~RBTree() {
template<typename K, typename V, typename COMPARATOR, typename ALLOCATOR>
bool RBTree<K, V, COMPARATOR, ALLOCATOR>::copy_into(RBTree& other) const {
assert(other.size() == 0, "You can only copy into an empty RBTree");
assert(std::is_copy_constructible<K>::value, "Key type must be copy-constructible when copying a RBTree");
assert(std::is_copy_constructible<V>::value, "Value type must be copy-constructible when copying a RBTree");
precond(other.size() == 0);
precond(std::is_copy_constructible<K>::value);
precond(std::is_copy_constructible<V>::value);
enum class Dir { Left, Right };
struct node_pair { const IntrusiveRBNode* current; IntrusiveRBNode* other_parent; Dir dir; };
struct stack {
@ -1098,6 +1105,9 @@ bool RBTree<K, V, COMPARATOR, ALLOCATOR>::copy_into(RBTree& other) const {
template <typename K, typename V, typename COMPARATOR, typename ALLOCATOR>
inline void RBTree<K, V, COMPARATOR, ALLOCATOR>::replace_at_cursor(RBNode<K, V>* new_node, const Cursor& node_cursor) {
precond(new_node != nullptr);
precond(node_cursor.valid());
precond(node_cursor.found());
RBNode<K, V>* old_node = node_cursor.node();
BaseType::replace_at_cursor(new_node, node_cursor);
free_node(old_node);
@ -1123,6 +1133,7 @@ inline RBNode<K, V>* RBTree<K, V, COMPARATOR, ALLOCATOR>::allocate_node(const K&
template <typename K, typename V, typename COMPARATOR, typename ALLOCATOR>
inline void RBTree<K, V, COMPARATOR, ALLOCATOR>::free_node(RBNode<K, V>* node) {
precond(node != nullptr);
node->_value.~V();
_allocator.free(node);
}