mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-01 16:04:33 +01:00
Merge #225
225: A fix that stops panics from the old MaybeUninit impl r=korken89 a=korken89
Sometimes when running in debug mode the current implementation of `MaybeUninit` would panic, an example can be found here: 2bb89427fa/examples/rtfm-uarte-interrupts/src/main.rs (L106)
On debug this line will always panic, on release all is fine.
The issue seemed to be the manual `MaybeUninit` implementation, so I have merged the two implementations together.
Please have a look and see if my fix is unsound (it does however work, but not sure on UB).
cc @japaric @TeXitoi
Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
This commit is contained in:
commit
34a2767bdf
6 changed files with 22 additions and 59 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
## Требования
|
||||
|
||||
- Rust 1.31.0+
|
||||
- Rust 1.36.0+
|
||||
|
||||
- Программы нужно писать используя 2018 edition.
|
||||
|
||||
|
|
|
@ -1948,13 +1948,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
|
||||
|
|
|
@ -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)]
|
||||
|
@ -64,13 +62,11 @@ impl Priority {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
pub struct MaybeUninit<T> {
|
||||
// we newtype so the end-user doesn't need `#![feature(maybe_uninit)]` in their code
|
||||
inner: core::mem::MaybeUninit<T>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
impl<T> MaybeUninit<T> {
|
||||
pub const fn uninit() -> Self {
|
||||
MaybeUninit {
|
||||
|
@ -86,61 +82,23 @@ impl<T> MaybeUninit<T> {
|
|||
self.inner.as_mut_ptr()
|
||||
}
|
||||
|
||||
pub fn write(&mut self, value: T) -> &mut T {
|
||||
self.inner.write(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
pub struct MaybeUninit<T> {
|
||||
value: Option<T>,
|
||||
}
|
||||
|
||||
#[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<T> MaybeUninit<T> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_ref(&self) -> &T {
|
||||
if let Some(x) = self.value.as_ref() {
|
||||
x
|
||||
} else {
|
||||
unreachable!(MSG)
|
||||
}
|
||||
&*self.inner.as_ptr()
|
||||
}
|
||||
|
||||
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(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);
|
||||
unsafe { self.get_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -41,7 +41,7 @@
|
|||
//! 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)]
|
||||
#![no_std]
|
||||
|
|
Loading…
Reference in a new issue