diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2020-10-14 06:02:21 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-14 06:02:21 +0900 |
| commit | cc5a1aad4e2d45ab4da71a1807da9aa6f9e846aa (patch) | |
| tree | 623614a69ee529ffd304eab8c4e044ff4d680741 | |
| parent | 7de5fe76f25304cb5a34b81a3989c6117b0761f0 (diff) | |
| parent | af414dc274d30bc3f4aea1d396ac2663e0c08c56 (diff) | |
| download | rust-cc5a1aad4e2d45ab4da71a1807da9aa6f9e846aa.tar.gz rust-cc5a1aad4e2d45ab4da71a1807da9aa6f9e846aa.zip | |
Rollup merge of #77722 - fusion-engineering-forks:safe-unsupported-locks, r=Mark-Simulacrum
Remove unsafety from sys/unsupported and add deny(unsafe_op_in_unsafe_fn). Replacing `UnsafeCell`s by a `Cell`s simplifies things and makes the mutex and rwlock implementations safe. Other than that, only unsafety in strlen() contained unsafe code. @rustbot modify labels: +F-unsafe-block-in-unsafe-fn +C-cleanup
| -rw-r--r-- | library/std/src/sys/unsupported/common.rs | 13 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/mod.rs | 2 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/mutex.rs | 21 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/rwlock.rs | 33 | ||||
| -rw-r--r-- | library/std/src/sys/wasi/mod.rs | 1 | ||||
| -rw-r--r-- | library/std/src/sys/wasm/mod.rs | 1 |
6 files changed, 34 insertions, 37 deletions
diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs index 80311d26819..2cdd9c4d19e 100644 --- a/library/std/src/sys/unsupported/common.rs +++ b/library/std/src/sys/unsupported/common.rs @@ -39,10 +39,13 @@ pub fn hashmap_random_keys() -> (u64, u64) { pub enum Void {} pub unsafe fn strlen(mut s: *const c_char) -> usize { - let mut n = 0; - while *s != 0 { - n += 1; - s = s.offset(1); + // SAFETY: The caller must guarantee `s` points to a valid 0-terminated string. + unsafe { + let mut n = 0; + while *s != 0 { + n += 1; + s = s.offset(1); + } + n } - return n; } diff --git a/library/std/src/sys/unsupported/mod.rs b/library/std/src/sys/unsupported/mod.rs index 8ba870c5dbc..d9efdec33d9 100644 --- a/library/std/src/sys/unsupported/mod.rs +++ b/library/std/src/sys/unsupported/mod.rs @@ -1,3 +1,5 @@ +#![deny(unsafe_op_in_unsafe_fn)] + pub mod alloc; pub mod args; pub mod cmath; diff --git a/library/std/src/sys/unsupported/mutex.rs b/library/std/src/sys/unsupported/mutex.rs index ed4605f0595..b3203c16c50 100644 --- a/library/std/src/sys/unsupported/mutex.rs +++ b/library/std/src/sys/unsupported/mutex.rs @@ -1,7 +1,8 @@ -use crate::cell::UnsafeCell; +use crate::cell::Cell; pub struct Mutex { - locked: UnsafeCell<bool>, + // This platform has no threads, so we can use a Cell here. + locked: Cell<bool>, } pub type MovableMutex = Mutex; @@ -11,7 +12,7 @@ unsafe impl Sync for Mutex {} // no threads on this platform impl Mutex { pub const fn new() -> Mutex { - Mutex { locked: UnsafeCell::new(false) } + Mutex { locked: Cell::new(false) } } #[inline] @@ -19,25 +20,17 @@ impl Mutex { #[inline] pub unsafe fn lock(&self) { - let locked = self.locked.get(); - assert!(!*locked, "cannot recursively acquire mutex"); - *locked = true; + assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex"); } #[inline] pub unsafe fn unlock(&self) { - *self.locked.get() = false; + self.locked.set(false); } #[inline] pub unsafe fn try_lock(&self) -> bool { - let locked = self.locked.get(); - if *locked { - false - } else { - *locked = true; - true - } + self.locked.replace(true) == false } #[inline] diff --git a/library/std/src/sys/unsupported/rwlock.rs b/library/std/src/sys/unsupported/rwlock.rs index d37f34ac935..6982b2b155f 100644 --- a/library/std/src/sys/unsupported/rwlock.rs +++ b/library/std/src/sys/unsupported/rwlock.rs @@ -1,7 +1,8 @@ -use crate::cell::UnsafeCell; +use crate::cell::Cell; pub struct RWLock { - mode: UnsafeCell<isize>, + // This platform has no threads, so we can use a Cell here. + mode: Cell<isize>, } unsafe impl Send for RWLock {} @@ -9,14 +10,14 @@ unsafe impl Sync for RWLock {} // no threads on this platform impl RWLock { pub const fn new() -> RWLock { - RWLock { mode: UnsafeCell::new(0) } + RWLock { mode: Cell::new(0) } } #[inline] pub unsafe fn read(&self) { - let mode = self.mode.get(); - if *mode >= 0 { - *mode += 1; + let m = self.mode.get(); + if m >= 0 { + self.mode.set(m + 1); } else { rtabort!("rwlock locked for writing"); } @@ -24,9 +25,9 @@ impl RWLock { #[inline] pub unsafe fn try_read(&self) -> bool { - let mode = self.mode.get(); - if *mode >= 0 { - *mode += 1; + let m = self.mode.get(); + if m >= 0 { + self.mode.set(m + 1); true } else { false @@ -35,19 +36,15 @@ impl RWLock { #[inline] pub unsafe fn write(&self) { - let mode = self.mode.get(); - if *mode == 0 { - *mode = -1; - } else { + if self.mode.replace(-1) != 0 { rtabort!("rwlock locked for reading") } } #[inline] pub unsafe fn try_write(&self) -> bool { - let mode = self.mode.get(); - if *mode == 0 { - *mode = -1; + if self.mode.get() == 0 { + self.mode.set(-1); true } else { false @@ -56,12 +53,12 @@ impl RWLock { #[inline] pub unsafe fn read_unlock(&self) { - *self.mode.get() -= 1; + self.mode.set(self.mode.get() - 1); } #[inline] pub unsafe fn write_unlock(&self) { - *self.mode.get() += 1; + assert_eq!(self.mode.replace(0), -1); } #[inline] diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs index a7a4407ac38..a0a37ef8316 100644 --- a/library/std/src/sys/wasi/mod.rs +++ b/library/std/src/sys/wasi/mod.rs @@ -53,6 +53,7 @@ pub mod thread_local_key; pub mod time; #[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] #[allow(unused)] mod common; pub use common::*; diff --git a/library/std/src/sys/wasm/mod.rs b/library/std/src/sys/wasm/mod.rs index 2934ea59ab5..18295e1129a 100644 --- a/library/std/src/sys/wasm/mod.rs +++ b/library/std/src/sys/wasm/mod.rs @@ -66,5 +66,6 @@ cfg_if::cfg_if! { } #[path = "../unsupported/common.rs"] +#[deny(unsafe_op_in_unsafe_fn)] mod common; pub use common::*; |
