From d5b665e28f2996eaf69af6b4afecf3ba7e0d47cb Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 9 Aug 2019 14:08:44 +0200 Subject: [PATCH 1/8] A fix that stops panics from the old MaybeUninit impl --- src/export.rs | 59 +++++++++++---------------------------------------- 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/src/export.rs b/src/export.rs index cf7293b620..2f08b2678c 100644 --- a/src/export.rs +++ b/src/export.rs @@ -64,13 +64,11 @@ impl Priority { } } -#[cfg(feature = "nightly")] pub struct MaybeUninit { // we newtype so the end-user doesn't need `#![feature(maybe_uninit)]` in their code inner: core::mem::MaybeUninit, } -#[cfg(feature = "nightly")] impl MaybeUninit { pub const fn uninit() -> Self { MaybeUninit { @@ -86,61 +84,28 @@ impl MaybeUninit { self.inner.as_mut_ptr() } + #[cfg(feature = "nightly")] pub fn write(&mut self, value: T) -> &mut T { self.inner.write(value) } -} - -#[cfg(not(feature = "nightly"))] -pub struct MaybeUninit { - value: Option, -} - -#[cfg(not(feature = "nightly"))] -const MSG: &str = - "you have hit a bug (UB) in RTFM implementation; try enabling this crate 'nightly' feature"; - -#[cfg(not(feature = "nightly"))] -impl MaybeUninit { - pub const fn uninit() -> Self { - MaybeUninit { value: None } - } - - pub fn as_ptr(&self) -> *const T { - if let Some(x) = self.value.as_ref() { - x - } else { - unreachable!(MSG) - } - } - - pub fn as_mut_ptr(&mut self) -> *mut T { - if let Some(x) = self.value.as_mut() { - x - } else { - unreachable!(MSG) - } - } + #[cfg(not(feature = "nightly"))] pub unsafe fn get_ref(&self) -> &T { - if let Some(x) = self.value.as_ref() { - x - } else { - unreachable!(MSG) - } + &*self.inner.as_ptr() } + #[cfg(not(feature = "nightly"))] pub unsafe fn get_mut(&mut self) -> &mut T { - if let Some(x) = self.value.as_mut() { - x - } else { - unreachable!(MSG) - } + &mut *self.inner.as_mut_ptr() } - pub fn write(&mut self, val: T) { - // NOTE(volatile) we have observed UB when this uses a plain `ptr::write` - unsafe { ptr::write_volatile(&mut self.value, Some(val)) } + #[cfg(not(feature = "nightly"))] + pub fn write(&mut self, value: T) -> &mut T { + let ptr = self.inner.as_mut_ptr(); + unsafe { + ptr::write_volatile(ptr, value); + &mut *ptr + } } } From 51a1aae17dfef6a5d212739a203c6f883a079160 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 9 Aug 2019 14:23:13 +0200 Subject: [PATCH 2/8] Added maybe_uninit_extra for CI --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index b0bf6689e3..571b8cfd78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ //! and may stop working at any time! #![cfg_attr(feature = "nightly", feature(maybe_uninit))] +#![cfg_attr(feature = "nightly", feature(maybe_uninit_extra))] #![deny(missing_docs)] #![deny(warnings)] #![no_std] From e9bc00bc9b5735104c6cad26c3cda06ae649e2e6 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 9 Aug 2019 14:28:04 +0200 Subject: [PATCH 3/8] Removed old flag --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 571b8cfd78..5160ba9a38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,6 @@ //! usage, runtime overhead and initialization overhead. This feature requires a nightly compiler //! and may stop working at any time! -#![cfg_attr(feature = "nightly", feature(maybe_uninit))] #![cfg_attr(feature = "nightly", feature(maybe_uninit_extra))] #![deny(missing_docs)] #![deny(warnings)] From 7de26409c2f260bccf06b617e9e0ba0d4d0aeb71 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 9 Aug 2019 14:56:40 +0200 Subject: [PATCH 4/8] Better impl of write --- src/export.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/export.rs b/src/export.rs index 2f08b2678c..a0d40a93bb 100644 --- a/src/export.rs +++ b/src/export.rs @@ -1,7 +1,5 @@ //! IMPLEMENTATION DETAILS. DO NOT USE ANYTHING IN THIS MODULE -#[cfg(not(feature = "nightly"))] -use core::ptr; use core::{cell::Cell, u8}; #[cfg(armv7m)] @@ -101,11 +99,8 @@ impl MaybeUninit { #[cfg(not(feature = "nightly"))] pub fn write(&mut self, value: T) -> &mut T { - let ptr = self.inner.as_mut_ptr(); - unsafe { - ptr::write_volatile(ptr, value); - &mut *ptr - } + self.inner = core::mem::MaybeUninit::new(value); + unsafe { self.get_mut() } } } From 2e3a88999154952bd1c3c557695cdb46d930104d Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Fri, 9 Aug 2019 14:57:12 +0200 Subject: [PATCH 5/8] Added get_mut and get_ref into the nightly as well --- src/export.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/export.rs b/src/export.rs index a0d40a93bb..e75d25ad2b 100644 --- a/src/export.rs +++ b/src/export.rs @@ -82,21 +82,19 @@ impl MaybeUninit { self.inner.as_mut_ptr() } - #[cfg(feature = "nightly")] - pub fn write(&mut self, value: T) -> &mut T { - self.inner.write(value) - } - - #[cfg(not(feature = "nightly"))] pub unsafe fn get_ref(&self) -> &T { &*self.inner.as_ptr() } - #[cfg(not(feature = "nightly"))] pub unsafe fn get_mut(&mut self) -> &mut T { &mut *self.inner.as_mut_ptr() } + #[cfg(feature = "nightly")] + pub fn write(&mut self, value: T) -> &mut T { + self.inner.write(value) + } + #[cfg(not(feature = "nightly"))] pub fn write(&mut self, value: T) -> &mut T { self.inner = core::mem::MaybeUninit::new(value); From a1abbbbea730eb7ff51e1f51c228db298ff8a6fb Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Wed, 23 Oct 2019 20:33:50 +0200 Subject: [PATCH 6/8] Fixed mem::uninitialized warnings --- macros/src/codegen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 4468216f53..9bd8836033 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -1949,13 +1949,13 @@ fn pre_init(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::Toke // these are `MaybeUninit` arrays for task in ctxt.tasks.values() { let inputs = &task.inputs; - exprs.push(quote!(#inputs.write(core::mem::uninitialized());)) + exprs.push(quote!(#inputs.write(core::mem::MaybeUninit::uninit());)) } #[cfg(feature = "timer-queue")] for task in ctxt.tasks.values() { let scheduleds = &task.scheduleds; - exprs.push(quote!(#scheduleds.write(core::mem::uninitialized());)) + exprs.push(quote!(#scheduleds.write(core::mem::MaybeUninit::uninit());)) } // these are `MaybeUninit` `ReadyQueue`s From 63a0c4a1e8b5ba3cad337096df09191a4d290935 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Wed, 23 Oct 2019 21:41:27 +0200 Subject: [PATCH 7/8] Updated MSRV due to fix --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5160ba9a38..6471281a36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ //! //! # Minimum Supported Rust Version (MSRV) //! -//! This crate is guaranteed to compile on stable Rust 1.31 (2018 edition) and up. It *might* +//! This crate is guaranteed to compile on stable Rust 1.36 (2018 edition) and up. It *might* //! compile on older versions but that may change in any new patch release. //! //! # Semantic Versioning From abcf9bf61d2820306b489b84e2311617c6f88e1f Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Wed, 23 Oct 2019 21:48:44 +0200 Subject: [PATCH 8/8] Docs updates --- CHANGELOG.md | 5 +++++ README.md | 2 +- book/ru/src/README_RU.md | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df4c674d32..be29986714 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed + +- Soundness issue in the `MaybeUninit` implementation +- Warning for deprecated `mem::uninitialized` + ## [v0.4.3] - 2019-04-21 ### Changed diff --git a/README.md b/README.md index b8cbd00f7d..bf2ba83b9e 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ A concurrency framework for building real time systems. ## Requirements -- Rust 1.31.0+ +- Rust 1.36.0+ - Applications must be written using the 2018 edition. diff --git a/book/ru/src/README_RU.md b/book/ru/src/README_RU.md index 921837a928..cb5124e23a 100644 --- a/book/ru/src/README_RU.md +++ b/book/ru/src/README_RU.md @@ -39,7 +39,7 @@ ## Требования -- Rust 1.31.0+ +- Rust 1.36.0+ - Программы нужно писать используя 2018 edition.