Skip to content

Commit fddf51e

Browse files
glandiumSimonSapin
authored andcommitted
Use NonNull<Void> instead of *mut u8 in the Alloc trait
Fixes #49608
1 parent fd242ee commit fddf51e

File tree

18 files changed

+136
-129
lines changed

18 files changed

+136
-129
lines changed

src/doc/nomicon

src/doc/unstable-book/src/language-features/global-allocator.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ looks like:
3030
#![feature(global_allocator, allocator_api, heap_api)]
3131

3232
use std::alloc::{GlobalAlloc, System, Layout, Void};
33+
use std::ptr::NonNull;
3334

3435
struct MyAllocator;
3536

src/liballoc/alloc.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
issue = "32838")]
1717

1818
use core::intrinsics::{min_align_of_val, size_of_val};
19+
use core::ptr::NonNull;
1920
use core::usize;
2021

2122
#[doc(inline)]
@@ -120,27 +121,27 @@ unsafe impl GlobalAlloc for Global {
120121

121122
unsafe impl Alloc for Global {
122123
#[inline]
123-
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
124+
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Void>, AllocErr> {
124125
GlobalAlloc::alloc(self, layout).into()
125126
}
126127

127128
#[inline]
128-
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
129-
GlobalAlloc::dealloc(self, ptr as *mut Void, layout)
129+
unsafe fn dealloc(&mut self, ptr: NonNull<Void>, layout: Layout) {
130+
GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
130131
}
131132

132133
#[inline]
133134
unsafe fn realloc(&mut self,
134-
ptr: *mut u8,
135+
ptr: NonNull<Void>,
135136
layout: Layout,
136137
new_size: usize)
137-
-> Result<*mut u8, AllocErr>
138+
-> Result<NonNull<Void>, AllocErr>
138139
{
139-
GlobalAlloc::realloc(self, ptr as *mut Void, layout, new_size).into()
140+
GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size).into()
140141
}
141142

142143
#[inline]
143-
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
144+
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Void>, AllocErr> {
144145
GlobalAlloc::alloc_zeroed(self, layout).into()
145146
}
146147

@@ -195,8 +196,8 @@ mod tests {
195196
let ptr = Global.alloc_zeroed(layout.clone())
196197
.unwrap_or_else(|_| Global.oom());
197198

198-
let end = ptr.offset(layout.size() as isize);
199-
let mut i = ptr;
199+
let mut i = ptr.cast::<u8>().as_ptr();
200+
let end = i.offset(layout.size() as isize);
200201
while i < end {
201202
assert_eq!(*i, 0);
202203
i = i.offset(1);

src/liballoc/arc.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -512,15 +512,13 @@ impl<T: ?Sized> Arc<T> {
512512
// Non-inlined part of `drop`.
513513
#[inline(never)]
514514
unsafe fn drop_slow(&mut self) {
515-
let ptr = self.ptr.as_ptr();
516-
517515
// Destroy the data at this time, even though we may not free the box
518516
// allocation itself (there may still be weak pointers lying around).
519517
ptr::drop_in_place(&mut self.ptr.as_mut().data);
520518

521519
if self.inner().weak.fetch_sub(1, Release) == 1 {
522520
atomic::fence(Acquire);
523-
Global.dealloc(ptr as *mut u8, Layout::for_value(&*ptr))
521+
Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref()))
524522
}
525523
}
526524

@@ -558,7 +556,7 @@ impl<T: ?Sized> Arc<T> {
558556
.unwrap_or_else(|_| Global.oom());
559557

560558
// Initialize the real ArcInner
561-
let inner = set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>;
559+
let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner<T>;
562560

563561
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
564562
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
@@ -625,7 +623,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
625623
// In the event of a panic, elements that have been written
626624
// into the new ArcInner will be dropped, then the memory freed.
627625
struct Guard<T> {
628-
mem: *mut u8,
626+
mem: NonNull<u8>,
629627
elems: *mut T,
630628
layout: Layout,
631629
n_elems: usize,
@@ -639,7 +637,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
639637
let slice = from_raw_parts_mut(self.elems, self.n_elems);
640638
ptr::drop_in_place(slice);
641639

642-
Global.dealloc(self.mem, self.layout.clone());
640+
Global.dealloc(self.mem.as_void(), self.layout.clone());
643641
}
644642
}
645643
}
@@ -655,7 +653,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
655653
let elems = &mut (*ptr).data as *mut [T] as *mut T;
656654

657655
let mut guard = Guard{
658-
mem: mem,
656+
mem: NonNull::new_unchecked(mem),
659657
elems: elems,
660658
layout: layout,
661659
n_elems: 0,
@@ -1147,8 +1145,6 @@ impl<T: ?Sized> Drop for Weak<T> {
11471145
/// assert!(other_weak_foo.upgrade().is_none());
11481146
/// ```
11491147
fn drop(&mut self) {
1150-
let ptr = self.ptr.as_ptr();
1151-
11521148
// If we find out that we were the last weak pointer, then its time to
11531149
// deallocate the data entirely. See the discussion in Arc::drop() about
11541150
// the memory orderings
@@ -1160,7 +1156,7 @@ impl<T: ?Sized> Drop for Weak<T> {
11601156
if self.inner().weak.fetch_sub(1, Release) == 1 {
11611157
atomic::fence(Acquire);
11621158
unsafe {
1163-
Global.dealloc(ptr as *mut u8, Layout::for_value(&*ptr))
1159+
Global.dealloc(self.ptr.as_void(), Layout::for_value(self.ptr.as_ref()))
11641160
}
11651161
}
11661162
}

src/liballoc/btree/node.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ impl<K, V> Root<K, V> {
236236
pub fn pop_level(&mut self) {
237237
debug_assert!(self.height > 0);
238238

239-
let top = self.node.ptr.as_ptr() as *mut u8;
239+
let top = self.node.ptr;
240240

241241
self.node = unsafe {
242242
BoxedNode::from_ptr(self.as_mut()
@@ -249,7 +249,7 @@ impl<K, V> Root<K, V> {
249249
self.as_mut().as_leaf_mut().parent = ptr::null();
250250

251251
unsafe {
252-
Global.dealloc(top, Layout::new::<InternalNode<K, V>>());
252+
Global.dealloc(NonNull::from(top).as_void(), Layout::new::<InternalNode<K, V>>());
253253
}
254254
}
255255
}
@@ -433,9 +433,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
433433
marker::Edge
434434
>
435435
> {
436-
let ptr = self.as_leaf() as *const LeafNode<K, V> as *const u8 as *mut u8;
436+
let node = self.node;
437437
let ret = self.ascend().ok();
438-
Global.dealloc(ptr, Layout::new::<LeafNode<K, V>>());
438+
Global.dealloc(node.as_void(), Layout::new::<LeafNode<K, V>>());
439439
ret
440440
}
441441
}
@@ -454,9 +454,9 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
454454
marker::Edge
455455
>
456456
> {
457-
let ptr = self.as_internal() as *const InternalNode<K, V> as *const u8 as *mut u8;
457+
let node = self.node;
458458
let ret = self.ascend().ok();
459-
Global.dealloc(ptr, Layout::new::<InternalNode<K, V>>());
459+
Global.dealloc(node.as_void(), Layout::new::<InternalNode<K, V>>());
460460
ret
461461
}
462462
}
@@ -1239,12 +1239,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
12391239
}
12401240

12411241
Global.dealloc(
1242-
right_node.node.as_ptr() as *mut u8,
1242+
right_node.node.as_void(),
12431243
Layout::new::<InternalNode<K, V>>(),
12441244
);
12451245
} else {
12461246
Global.dealloc(
1247-
right_node.node.as_ptr() as *mut u8,
1247+
right_node.node.as_void(),
12481248
Layout::new::<LeafNode<K, V>>(),
12491249
);
12501250
}

src/liballoc/heap.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
pub use alloc::{Excess, Layout, AllocErr, CannotReallocInPlace};
11+
#![allow(deprecated)]
12+
13+
pub use alloc::{Layout, AllocErr, CannotReallocInPlace, Void};
1214
use core::alloc::Alloc as CoreAlloc;
15+
use core::ptr::NonNull;
1316

1417
#[doc(hidden)]
1518
pub mod __core {
1619
pub use core::*;
1720
}
1821

22+
#[derive(Debug)]
23+
pub struct Excess(pub *mut u8, pub usize);
24+
1925
/// Compatibility with older versions of #[global_allocator] during bootstrap
2026
pub unsafe trait Alloc {
2127
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
@@ -42,13 +48,13 @@ pub unsafe trait Alloc {
4248
new_layout: Layout) -> Result<(), CannotReallocInPlace>;
4349
}
4450

45-
#[allow(deprecated)]
4651
unsafe impl<T> Alloc for T where T: CoreAlloc {
4752
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
48-
CoreAlloc::alloc(self, layout)
53+
CoreAlloc::alloc(self, layout).map(|ptr| ptr.cast().as_ptr())
4954
}
5055

5156
unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
57+
let ptr = NonNull::new_unchecked(ptr as *mut Void);
5258
CoreAlloc::dealloc(self, ptr, layout)
5359
}
5460

@@ -64,35 +70,41 @@ unsafe impl<T> Alloc for T where T: CoreAlloc {
6470
ptr: *mut u8,
6571
layout: Layout,
6672
new_layout: Layout) -> Result<*mut u8, AllocErr> {
67-
CoreAlloc::realloc(self, ptr, layout, new_layout.size())
73+
let ptr = NonNull::new_unchecked(ptr as *mut Void);
74+
CoreAlloc::realloc(self, ptr, layout, new_layout.size()).map(|ptr| ptr.cast().as_ptr())
6875
}
6976

7077
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
71-
CoreAlloc::alloc_zeroed(self, layout)
78+
CoreAlloc::alloc_zeroed(self, layout).map(|ptr| ptr.cast().as_ptr())
7279
}
7380

7481
unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
7582
CoreAlloc::alloc_excess(self, layout)
83+
.map(|e| Excess(e.0 .cast().as_ptr(), e.1))
7684
}
7785

7886
unsafe fn realloc_excess(&mut self,
7987
ptr: *mut u8,
8088
layout: Layout,
8189
new_layout: Layout) -> Result<Excess, AllocErr> {
90+
let ptr = NonNull::new_unchecked(ptr as *mut Void);
8291
CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size())
92+
.map(|e| Excess(e.0 .cast().as_ptr(), e.1))
8393
}
8494

8595
unsafe fn grow_in_place(&mut self,
8696
ptr: *mut u8,
8797
layout: Layout,
8898
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
99+
let ptr = NonNull::new_unchecked(ptr as *mut Void);
89100
CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size())
90101
}
91102

92103
unsafe fn shrink_in_place(&mut self,
93104
ptr: *mut u8,
94105
layout: Layout,
95106
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
107+
let ptr = NonNull::new_unchecked(ptr as *mut Void);
96108
CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size())
97109
}
98110
}

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
#![feature(lang_items)]
100100
#![feature(libc)]
101101
#![feature(needs_allocator)]
102+
#![feature(nonnull_cast)]
102103
#![feature(nonzero)]
103104
#![feature(optin_builtin_traits)]
104105
#![feature(pattern)]

0 commit comments

Comments
 (0)