Skip to content

Commit 2c308b9

Browse files
committed
Auto merge of #79347 - ssomers:btree_split_pointer_provenance, r=Mark-Simulacrum
BTreeMap: respect pointer provenance rules in split_off The test cases for `split_off` reported a few more violations (now that they support -Zmiri-track-raw-pointers). The functions `shift_kv` and `shift_edges` do not fix anything, I think, but if `move_kv` and `move_edges` exist, they deserve to live too. r? `@Mark-Simulacrum`
2 parents 0edce6f + 8824efd commit 2c308b9

File tree

1 file changed

+81
-97
lines changed
  • library/alloc/src/collections/btree

1 file changed

+81
-97
lines changed

library/alloc/src/collections/btree/node.rs

+81-97
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use core::cmp::Ordering;
3535
use core::marker::PhantomData;
3636
use core::mem::{self, MaybeUninit};
3737
use core::ptr::{self, NonNull};
38+
use core::slice::SliceIndex;
3839

3940
use crate::alloc::{Allocator, Global, Layout};
4041
use crate::boxed::Box;
@@ -507,30 +508,45 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
507508
/// Borrows exclusive access to an element of the key storage area.
508509
///
509510
/// # Safety
510-
/// The node has more than `idx` initialized elements.
511-
unsafe fn key_area_mut_at(&mut self, idx: usize) -> &mut MaybeUninit<K> {
512-
debug_assert!(idx < self.len());
513-
unsafe { self.as_leaf_mut().keys.get_unchecked_mut(idx) }
511+
/// `index` is in bounds of 0..CAPACITY
512+
unsafe fn key_area_mut_at<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
513+
where
514+
I: SliceIndex<[MaybeUninit<K>], Output = Output>,
515+
{
516+
// SAFETY: the caller will not be able to call further methods on self
517+
// until the key slice reference is dropped, as we have unique access
518+
// for the lifetime of the borrow.
519+
unsafe { self.as_leaf_mut().keys.as_mut_slice().get_unchecked_mut(index) }
514520
}
515521

516-
/// Borrows exclusive access to an element of the value storage area.
522+
/// Borrows exclusive access to an element or slice of the node's value storage area.
517523
///
518524
/// # Safety
519-
/// The node has more than `idx` initialized elements.
520-
unsafe fn val_area_mut_at(&mut self, idx: usize) -> &mut MaybeUninit<V> {
521-
debug_assert!(idx < self.len());
522-
unsafe { self.as_leaf_mut().vals.get_unchecked_mut(idx) }
525+
/// `index` is in bounds of 0..CAPACITY
526+
unsafe fn val_area_mut_at<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
527+
where
528+
I: SliceIndex<[MaybeUninit<V>], Output = Output>,
529+
{
530+
// SAFETY: the caller will not be able to call further methods on self
531+
// until the value slice reference is dropped, as we have unique access
532+
// for the lifetime of the borrow.
533+
unsafe { self.as_leaf_mut().vals.as_mut_slice().get_unchecked_mut(index) }
523534
}
524535
}
525536

526537
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
527-
/// Borrows exclusive access to an element of the storage area for edge contents.
538+
/// Borrows exclusive access to an element or slice of the node's storage area for edge contents.
528539
///
529540
/// # Safety
530-
/// The node has at least `idx` initialized elements.
531-
unsafe fn edge_area_mut_at(&mut self, idx: usize) -> &mut MaybeUninit<BoxedNode<K, V>> {
532-
debug_assert!(idx <= self.len());
533-
unsafe { self.as_internal_mut().edges.get_unchecked_mut(idx) }
541+
/// `index` is in bounds of 0..CAPACITY + 1
542+
unsafe fn edge_area_mut_at<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
543+
where
544+
I: SliceIndex<[MaybeUninit<BoxedNode<K, V>>], Output = Output>,
545+
{
546+
// SAFETY: the caller will not be able to call further methods on self
547+
// until the edge slice reference is dropped, as we have unique access
548+
// for the lifetime of the borrow.
549+
unsafe { self.as_internal_mut().edges.as_mut_slice().get_unchecked_mut(index) }
534550
}
535551
}
536552

@@ -559,37 +575,6 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, K, V, marker::Internal> {
559575
}
560576
}
561577

562-
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
563-
/// Borrows exclusive access to a sized slice of key storage area in the node.
564-
unsafe fn key_area_slice(&mut self) -> &mut [MaybeUninit<K>] {
565-
let len = self.len();
566-
// SAFETY: the caller will not be able to call further methods on self
567-
// until the key slice reference is dropped, as we have unique access
568-
// for the lifetime of the borrow.
569-
unsafe { self.as_leaf_mut().keys.get_unchecked_mut(..len) }
570-
}
571-
572-
/// Borrows exclusive access to a sized slice of value storage area in the node.
573-
unsafe fn val_area_slice(&mut self) -> &mut [MaybeUninit<V>] {
574-
let len = self.len();
575-
// SAFETY: the caller will not be able to call further methods on self
576-
// until the value slice reference is dropped, as we have unique access
577-
// for the lifetime of the borrow.
578-
unsafe { self.as_leaf_mut().vals.get_unchecked_mut(..len) }
579-
}
580-
}
581-
582-
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
583-
/// Borrows exclusive access to a sized slice of storage area for edge contents in the node.
584-
unsafe fn edge_area_slice(&mut self) -> &mut [MaybeUninit<BoxedNode<K, V>>] {
585-
let len = self.len();
586-
// SAFETY: the caller will not be able to call further methods on self
587-
// until the edge slice reference is dropped, as we have unique access
588-
// for the lifetime of the borrow.
589-
unsafe { self.as_internal_mut().edges.get_unchecked_mut(..len + 1) }
590-
}
591-
}
592-
593578
impl<'a, K, V, Type> NodeRef<marker::ValMut<'a>, K, V, Type> {
594579
/// # Safety
595580
/// - The node has more than `idx` initialized elements.
@@ -650,12 +635,12 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
650635

651636
/// Adds a key-value pair to the beginning of the node.
652637
fn push_front(&mut self, key: K, val: V) {
653-
assert!(self.len() < CAPACITY);
654-
638+
let new_len = self.len() + 1;
639+
assert!(new_len <= CAPACITY);
655640
unsafe {
656-
*self.len_mut() += 1;
657-
slice_insert(self.key_area_slice(), 0, key);
658-
slice_insert(self.val_area_slice(), 0, val);
641+
slice_insert(self.key_area_mut_at(..new_len), 0, key);
642+
slice_insert(self.val_area_mut_at(..new_len), 0, val);
643+
*self.len_mut() = new_len as u16;
659644
}
660645
}
661646
}
@@ -697,14 +682,15 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
697682
/// Adds a key-value pair, and an edge to go to the left of that pair,
698683
/// to the beginning of the node.
699684
fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) {
685+
let new_len = self.len() + 1;
700686
assert!(edge.height == self.height - 1);
701-
assert!(self.len() < CAPACITY);
687+
assert!(new_len <= CAPACITY);
702688

703689
unsafe {
704-
*self.len_mut() += 1;
705-
slice_insert(self.key_area_slice(), 0, key);
706-
slice_insert(self.val_area_slice(), 0, val);
707-
slice_insert(self.edge_area_slice(), 0, edge.node);
690+
slice_insert(self.key_area_mut_at(..new_len), 0, key);
691+
slice_insert(self.val_area_mut_at(..new_len), 0, val);
692+
slice_insert(self.edge_area_mut_at(..new_len + 1), 0, edge.node);
693+
*self.len_mut() = new_len as u16;
708694
}
709695

710696
self.correct_all_childrens_parent_links();
@@ -749,12 +735,12 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
749735
let old_len = self.len();
750736

751737
unsafe {
752-
let key = slice_remove(self.key_area_slice(), 0);
753-
let val = slice_remove(self.val_area_slice(), 0);
738+
let key = slice_remove(self.key_area_mut_at(..old_len), 0);
739+
let val = slice_remove(self.val_area_mut_at(..old_len), 0);
754740
let edge = match self.reborrow_mut().force() {
755741
ForceResult::Leaf(_) => None,
756742
ForceResult::Internal(mut internal) => {
757-
let node = slice_remove(internal.edge_area_slice(), 0);
743+
let node = slice_remove(internal.edge_area_mut_at(..old_len + 1), 0);
758744
let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData };
759745
// Currently, clearing the parent link is superfluous, because we will
760746
// insert the node elsewhere and set its parent link again.
@@ -975,11 +961,12 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
975961
/// The returned pointer points to the inserted value.
976962
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
977963
debug_assert!(self.node.len() < CAPACITY);
964+
let new_len = self.node.len() + 1;
978965

979966
unsafe {
980-
*self.node.len_mut() += 1;
981-
slice_insert(self.node.key_area_slice(), self.idx, key);
982-
slice_insert(self.node.val_area_slice(), self.idx, val);
967+
slice_insert(self.node.key_area_mut_at(..new_len), self.idx, key);
968+
slice_insert(self.node.val_area_mut_at(..new_len), self.idx, val);
969+
*self.node.len_mut() = new_len as u16;
983970

984971
self.node.val_area_mut_at(self.idx).assume_init_mut()
985972
}
@@ -1033,14 +1020,15 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
10331020
fn insert_fit(&mut self, key: K, val: V, edge: Root<K, V>) {
10341021
debug_assert!(self.node.len() < CAPACITY);
10351022
debug_assert!(edge.height == self.node.height - 1);
1023+
let new_len = self.node.len() + 1;
10361024

10371025
unsafe {
1038-
*self.node.len_mut() += 1;
1039-
slice_insert(self.node.key_area_slice(), self.idx, key);
1040-
slice_insert(self.node.val_area_slice(), self.idx, val);
1041-
slice_insert(self.node.edge_area_slice(), self.idx + 1, edge.node);
1026+
slice_insert(self.node.key_area_mut_at(..new_len), self.idx, key);
1027+
slice_insert(self.node.val_area_mut_at(..new_len), self.idx, val);
1028+
slice_insert(self.node.edge_area_mut_at(..new_len + 1), self.idx + 1, edge.node);
1029+
*self.node.len_mut() = new_len as u16;
10421030

1043-
self.node.correct_childrens_parent_links((self.idx + 1)..=self.node.len());
1031+
self.node.correct_childrens_parent_links(self.idx + 1..new_len + 1);
10441032
}
10451033
}
10461034

@@ -1177,17 +1165,11 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>
11771165
}
11781166

11791167
impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
1180-
/// Helps implementations of `split` for a particular `NodeType`,
1181-
/// by calculating the length of the new node.
1182-
fn split_new_node_len(&self) -> usize {
1183-
debug_assert!(self.idx < self.node.len());
1184-
self.node.len() - self.idx - 1
1185-
}
1186-
11871168
/// Helps implementations of `split` for a particular `NodeType`,
11881169
/// by taking care of leaf data.
11891170
fn split_leaf_data(&mut self, new_node: &mut LeafNode<K, V>) -> (K, V) {
1190-
let new_len = self.split_new_node_len();
1171+
debug_assert!(self.idx < self.node.len());
1172+
let new_len = self.node.len() - self.idx - 1;
11911173
new_node.len = new_len as u16;
11921174
unsafe {
11931175
let k = ptr::read(self.node.reborrow().key_at(self.idx));
@@ -1234,10 +1216,11 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
12341216
pub fn remove(
12351217
mut self,
12361218
) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
1219+
let old_len = self.node.len();
12371220
unsafe {
1238-
let k = slice_remove(self.node.key_area_slice(), self.idx);
1239-
let v = slice_remove(self.node.val_area_slice(), self.idx);
1240-
*self.node.len_mut() -= 1;
1221+
let k = slice_remove(self.node.key_area_mut_at(..old_len), self.idx);
1222+
let v = slice_remove(self.node.val_area_mut_at(..old_len), self.idx);
1223+
*self.node.len_mut() = (old_len - 1) as u16;
12411224
((k, v), self.left_edge())
12421225
}
12431226
}
@@ -1254,14 +1237,13 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
12541237
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Internal> {
12551238
unsafe {
12561239
let mut new_node = Box::new(InternalNode::new());
1257-
let new_len = self.split_new_node_len();
1258-
// Move edges out before reducing length:
1240+
let kv = self.split_leaf_data(&mut new_node.data);
1241+
let new_len = usize::from(new_node.data.len);
12591242
ptr::copy_nonoverlapping(
12601243
self.node.reborrow().edge_area().as_ptr().add(self.idx + 1),
12611244
new_node.edges.as_mut_ptr(),
12621245
new_len + 1,
12631246
);
1264-
let kv = self.split_leaf_data(&mut new_node.data);
12651247

12661248
let height = self.node.height;
12671249
let mut right = NodeRef::from_new_internal(new_node, height);
@@ -1384,23 +1366,25 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
13841366
unsafe {
13851367
*left_node.len_mut() = new_left_len as u16;
13861368

1387-
let parent_key = slice_remove(parent_node.key_area_slice(), parent_idx);
1369+
let parent_key =
1370+
slice_remove(parent_node.key_area_mut_at(..old_parent_len), parent_idx);
13881371
left_node.key_area_mut_at(old_left_len).write(parent_key);
13891372
ptr::copy_nonoverlapping(
13901373
right_node.reborrow().key_area().as_ptr(),
1391-
left_node.key_area_slice().as_mut_ptr().add(old_left_len + 1),
1374+
left_node.key_area_mut_at(old_left_len + 1..).as_mut_ptr(),
13921375
right_len,
13931376
);
13941377

1395-
let parent_val = slice_remove(parent_node.val_area_slice(), parent_idx);
1378+
let parent_val =
1379+
slice_remove(parent_node.val_area_mut_at(..old_parent_len), parent_idx);
13961380
left_node.val_area_mut_at(old_left_len).write(parent_val);
13971381
ptr::copy_nonoverlapping(
13981382
right_node.reborrow().val_area().as_ptr(),
1399-
left_node.val_area_slice().as_mut_ptr().add(old_left_len + 1),
1383+
left_node.val_area_mut_at(old_left_len + 1..).as_mut_ptr(),
14001384
right_len,
14011385
);
14021386

1403-
slice_remove(&mut parent_node.edge_area_slice(), parent_idx + 1);
1387+
slice_remove(&mut parent_node.edge_area_mut_at(..old_parent_len + 1), parent_idx + 1);
14041388
parent_node.correct_childrens_parent_links(parent_idx + 1..old_parent_len);
14051389
*parent_node.len_mut() -= 1;
14061390

@@ -1411,7 +1395,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
14111395
let right_node = right_node.cast_to_internal_unchecked();
14121396
ptr::copy_nonoverlapping(
14131397
right_node.reborrow().edge_area().as_ptr(),
1414-
left_node.edge_area_slice().as_mut_ptr().add(old_left_len + 1),
1398+
left_node.edge_area_mut_at(old_left_len + 1..).as_mut_ptr(),
14151399
right_len + 1,
14161400
);
14171401

@@ -1489,6 +1473,9 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
14891473
assert!(old_left_len >= count);
14901474

14911475
let new_left_len = old_left_len - count;
1476+
let new_right_len = old_right_len + count;
1477+
*left_node.len_mut() = new_left_len as u16;
1478+
*right_node.len_mut() = new_right_len as u16;
14921479

14931480
// Move leaf data.
14941481
{
@@ -1513,16 +1500,13 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
15131500
move_kv(left_kv, new_left_len, parent_kv, 0, 1);
15141501
}
15151502

1516-
*left_node.len_mut() -= count as u16;
1517-
*right_node.len_mut() += count as u16;
1518-
15191503
match (left_node.reborrow_mut().force(), right_node.reborrow_mut().force()) {
15201504
(ForceResult::Internal(left), ForceResult::Internal(mut right)) => {
15211505
// Make room for stolen edges.
15221506
let left = left.reborrow();
1523-
let right_edges = right.edge_area_slice().as_mut_ptr();
1507+
let right_edges = right.edge_area_mut_at(..).as_mut_ptr();
15241508
ptr::copy(right_edges, right_edges.add(count), old_right_len + 1);
1525-
right.correct_childrens_parent_links(count..count + old_right_len + 1);
1509+
right.correct_childrens_parent_links(count..new_right_len + 1);
15261510

15271511
// Steal edges.
15281512
move_edges(left, new_left_len + 1, right, 0, count);
@@ -1546,7 +1530,10 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
15461530
assert!(old_left_len + count <= CAPACITY);
15471531
assert!(old_right_len >= count);
15481532

1533+
let new_left_len = old_left_len + count;
15491534
let new_right_len = old_right_len - count;
1535+
*left_node.len_mut() = new_left_len as u16;
1536+
*right_node.len_mut() = new_right_len as u16;
15501537

15511538
// Move leaf data.
15521539
{
@@ -1571,16 +1558,13 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
15711558
ptr::copy(right_kv.1.add(count), right_kv.1, new_right_len);
15721559
}
15731560

1574-
*left_node.len_mut() += count as u16;
1575-
*right_node.len_mut() -= count as u16;
1576-
15771561
match (left_node.reborrow_mut().force(), right_node.reborrow_mut().force()) {
15781562
(ForceResult::Internal(left), ForceResult::Internal(mut right)) => {
15791563
// Steal edges.
15801564
move_edges(right.reborrow(), 0, left, old_left_len + 1, count);
15811565

15821566
// Fill gap where stolen edges used to be.
1583-
let right_edges = right.edge_area_slice().as_mut_ptr();
1567+
let right_edges = right.edge_area_mut_at(..).as_mut_ptr();
15841568
ptr::copy(right_edges.add(count), right_edges, new_right_len + 1);
15851569
right.correct_childrens_parent_links(0..=new_right_len);
15861570
}
@@ -1614,8 +1598,8 @@ unsafe fn move_edges<'a, K: 'a, V: 'a>(
16141598
) {
16151599
unsafe {
16161600
let source_ptr = source.edge_area().as_ptr();
1617-
let dest_ptr = dest.edge_area_slice().as_mut_ptr();
1618-
ptr::copy_nonoverlapping(source_ptr.add(source_offset), dest_ptr.add(dest_offset), count);
1601+
let dest_ptr = dest.edge_area_mut_at(dest_offset..).as_mut_ptr();
1602+
ptr::copy_nonoverlapping(source_ptr.add(source_offset), dest_ptr, count);
16191603
dest.correct_childrens_parent_links(dest_offset..dest_offset + count);
16201604
}
16211605
}

0 commit comments

Comments
 (0)