Skip to content

Commit e0c08ae

Browse files
authored
Rollup merge of #74477 - chansuke:sys-wasm-unsafe-op-in-unsafe-fn, r=Mark-Simulacrum
`#[deny(unsafe_op_in_unsafe_fn)]` in sys/wasm This is part of #73904. This encloses unsafe operations in unsafe fn in `libstd/sys/wasm`. @rustbot modify labels: F-unsafe-block-in-unsafe-fn
2 parents b6ac411 + d37b8cf commit e0c08ae

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

library/std/src/sys/wasm/alloc.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,34 @@ static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;
2424
unsafe impl GlobalAlloc for System {
2525
#[inline]
2626
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
27+
// SAFETY: DLMALLOC access is guranteed to be safe because the lock gives us unique and non-reentrant access.
28+
// Calling malloc() is safe because preconditions on this function match the trait method preconditions.
2729
let _lock = lock::lock();
28-
DLMALLOC.malloc(layout.size(), layout.align())
30+
unsafe { DLMALLOC.malloc(layout.size(), layout.align()) }
2931
}
3032

3133
#[inline]
3234
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
35+
// SAFETY: DLMALLOC access is guranteed to be safe because the lock gives us unique and non-reentrant access.
36+
// Calling calloc() is safe because preconditions on this function match the trait method preconditions.
3337
let _lock = lock::lock();
34-
DLMALLOC.calloc(layout.size(), layout.align())
38+
unsafe { DLMALLOC.calloc(layout.size(), layout.align()) }
3539
}
3640

3741
#[inline]
3842
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
43+
// SAFETY: DLMALLOC access is guranteed to be safe because the lock gives us unique and non-reentrant access.
44+
// Calling free() is safe because preconditions on this function match the trait method preconditions.
3945
let _lock = lock::lock();
40-
DLMALLOC.free(ptr, layout.size(), layout.align())
46+
unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) }
4147
}
4248

4349
#[inline]
4450
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
51+
// SAFETY: DLMALLOC access is guranteed to be safe because the lock gives us unique and non-reentrant access.
52+
// Calling realloc() is safe because preconditions on this function match the trait method preconditions.
4553
let _lock = lock::lock();
46-
DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
54+
unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) }
4755
}
4856
}
4957

library/std/src/sys/wasm/condvar_atomics.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,19 @@ impl Condvar {
4444

4545
pub unsafe fn notify_one(&self) {
4646
self.cnt.fetch_add(1, SeqCst);
47-
wasm32::memory_atomic_notify(self.ptr(), 1);
47+
// SAFETY: ptr() is always valid
48+
unsafe {
49+
wasm32::memory_atomic_notify(self.ptr(), 1);
50+
}
4851
}
4952

5053
#[inline]
5154
pub unsafe fn notify_all(&self) {
5255
self.cnt.fetch_add(1, SeqCst);
53-
wasm32::memory_atomic_notify(self.ptr(), u32::MAX); // -1 == "wake everyone"
56+
// SAFETY: ptr() is always valid
57+
unsafe {
58+
wasm32::memory_atomic_notify(self.ptr(), u32::MAX); // -1 == "wake everyone"
59+
}
5460
}
5561

5662
pub unsafe fn wait(&self, mutex: &Mutex) {

library/std/src/sys/wasm/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
//! compiling for wasm. That way it's a compile time error for something that's
1515
//! guaranteed to be a runtime error!
1616
17+
#![deny(unsafe_op_in_unsafe_fn)]
18+
1719
pub mod alloc;
1820
pub mod args;
1921
#[path = "../unsupported/cmath.rs"]

library/std/src/sys/wasm/mutex_atomics.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ impl Mutex {
2828

2929
pub unsafe fn lock(&self) {
3030
while !self.try_lock() {
31-
let val = wasm32::memory_atomic_wait32(
32-
self.ptr(),
33-
1, // we expect our mutex is locked
34-
-1, // wait infinitely
35-
);
31+
// SAFETY: the caller must uphold the safety contract for `memory_atomic_wait32`.
32+
let val = unsafe {
33+
wasm32::memory_atomic_wait32(
34+
self.ptr(),
35+
1, // we expect our mutex is locked
36+
-1, // wait infinitely
37+
)
38+
};
3639
// we should have either woke up (0) or got a not-equal due to a
3740
// race (1). We should never time out (2)
3841
debug_assert!(val == 0 || val == 1);
@@ -93,19 +96,20 @@ impl ReentrantMutex {
9396
pub unsafe fn lock(&self) {
9497
let me = thread::my_id();
9598
while let Err(owner) = self._try_lock(me) {
96-
let val = wasm32::memory_atomic_wait32(self.ptr(), owner as i32, -1);
99+
// SAFETY: the caller must gurantee that `self.ptr()` and `owner` are valid i32.
100+
let val = unsafe { wasm32::memory_atomic_wait32(self.ptr(), owner as i32, -1) };
97101
debug_assert!(val == 0 || val == 1);
98102
}
99103
}
100104

101105
#[inline]
102106
pub unsafe fn try_lock(&self) -> bool {
103-
self._try_lock(thread::my_id()).is_ok()
107+
unsafe { self._try_lock(thread::my_id()).is_ok() }
104108
}
105109

106110
#[inline]
107111
unsafe fn _try_lock(&self, id: u32) -> Result<(), u32> {
108-
let id = id.checked_add(1).unwrap(); // make sure `id` isn't 0
112+
let id = id.checked_add(1).unwrap();
109113
match self.owner.compare_exchange(0, id, SeqCst, SeqCst) {
110114
// we transitioned from unlocked to locked
111115
Ok(_) => {
@@ -132,7 +136,10 @@ impl ReentrantMutex {
132136
match *self.recursions.get() {
133137
0 => {
134138
self.owner.swap(0, SeqCst);
135-
wasm32::memory_atomic_notify(self.ptr() as *mut i32, 1); // wake up one waiter, if any
139+
// SAFETY: the caller must gurantee that `self.ptr()` is valid i32.
140+
unsafe {
141+
wasm32::atomic_notify(self.ptr() as *mut i32, 1);
142+
} // wake up one waiter, if any
136143
}
137144
ref mut n => *n -= 1,
138145
}

0 commit comments

Comments
 (0)