Skip to content

use MaybeUninit instead of mem::uninitialized for Windows Mutex #56275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Dec 2, 2018
4 changes: 2 additions & 2 deletions src/liballoc/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
} else {
unsafe {
slice::from_raw_parts_mut(
self.as_leaf_mut().keys.get_mut() as *mut [K] as *mut K,
self.as_leaf_mut().keys.as_mut_ptr() as *mut K,
self.len()
)
}
Expand All @@ -613,7 +613,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
debug_assert!(!self.is_shared_root());
unsafe {
slice::from_raw_parts_mut(
self.as_leaf_mut().vals.get_mut() as *mut [V] as *mut V,
self.as_leaf_mut().vals.as_mut_ptr() as *mut V,
self.len()
)
}
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/fmt/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ fn float_to_decimal_common_exact<T>(fmt: &mut Formatter, num: &T,
unsafe {
let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64
let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized();
// FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized
// `MaybeUninit` (here and elsewhere in this file). Revisit this once
// we decided whether that is valid or not.
let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact,
*num, sign, precision,
false, buf.get_mut(), parts.get_mut());
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,9 @@ impl<T> MaybeUninit<T> {
///
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// state, otherwise this will immediately cause undefined behavior.
// FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
// to uninitialized data (e.g. in `libcore/fmt/float.rs`). We should make
// a final decision about the rules before stabilization.
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[inline(always)]
pub unsafe fn get_mut(&mut self) -> &mut T {
Expand Down
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@
#![feature(panic_info_message)]
#![feature(non_exhaustive)]
#![feature(alloc_layout_extra)]
#![feature(maybe_uninit)]

#![default_lib_allocator]

Expand Down
18 changes: 9 additions & 9 deletions src/libstd/sys/windows/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//! detect recursive locks.

use cell::UnsafeCell;
use mem;
use mem::{self, MaybeUninit};
use sync::atomic::{AtomicUsize, Ordering};
use sys::c;
use sys::compat;
Expand Down Expand Up @@ -157,34 +157,34 @@ fn kind() -> Kind {
return ret;
}

pub struct ReentrantMutex { inner: UnsafeCell<c::CRITICAL_SECTION> }
pub struct ReentrantMutex { inner: UnsafeCell<MaybeUninit<c::CRITICAL_SECTION>> }

unsafe impl Send for ReentrantMutex {}
unsafe impl Sync for ReentrantMutex {}

impl ReentrantMutex {
pub unsafe fn uninitialized() -> ReentrantMutex {
mem::uninitialized()
pub fn uninitialized() -> ReentrantMutex {
ReentrantMutex { inner: UnsafeCell::new(MaybeUninit::uninitialized()) }
}

pub unsafe fn init(&mut self) {
c::InitializeCriticalSection(self.inner.get());
c::InitializeCriticalSection((&mut *self.inner.get()).as_mut_ptr());
}

pub unsafe fn lock(&self) {
c::EnterCriticalSection(self.inner.get());
c::EnterCriticalSection((&mut *self.inner.get()).as_mut_ptr());
}

#[inline]
pub unsafe fn try_lock(&self) -> bool {
c::TryEnterCriticalSection(self.inner.get()) != 0
c::TryEnterCriticalSection((&mut *self.inner.get()).as_mut_ptr()) != 0
}

pub unsafe fn unlock(&self) {
c::LeaveCriticalSection(self.inner.get());
c::LeaveCriticalSection((&mut *self.inner.get()).as_mut_ptr());
}

pub unsafe fn destroy(&self) {
c::DeleteCriticalSection(self.inner.get());
c::DeleteCriticalSection((&mut *self.inner.get()).as_mut_ptr());
}
}