diff options
author | 2021-02-21 16:15:34 +0100 | |
---|---|---|
committer | 2021-02-21 16:15:34 +0100 | |
commit | 1a46345a2aa710c4ec5ea8fb6589424bc4450d0f (patch) | |
tree | 9204b0dec5b5efa3baa0d0468fc6c30a8964a1eb /macros/src/codegen | |
parent | 555f36857ec93bed26ff4249593992f500b7c4ab (diff) | |
download | rtic-1a46345a2aa710c4ec5ea8fb6589424bc4450d0f.tar.gz rtic-1a46345a2aa710c4ec5ea8fb6589424bc4450d0f.tar.zst rtic-1a46345a2aa710c4ec5ea8fb6589424bc4450d0f.zip |
Fixed UB in generated `Monotonic::now()`
Diffstat (limited to 'macros/src/codegen')
-rw-r--r-- | macros/src/codegen/post_init.rs | 2 | ||||
-rw-r--r-- | macros/src/codegen/timer_queue.rs | 17 |
2 files changed, 12 insertions, 7 deletions
diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index b6cf47c3..8ebcb12b 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -35,7 +35,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> { // Store the monotonic let name = util::monotonic_ident(&monotonic.to_string()); - stmts.push(quote!(#name.as_mut_ptr().write(monotonics.#idx);)); + stmts.push(quote!(#name = Some(monotonics.#idx);)); } // Enable the interrupts -- this completes the `init`-ialization phase diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 54b2c1f0..65560680 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -69,11 +69,11 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea let mono = util::monotonic_ident(&monotonic_name); let doc = &format!("Storage for {}", monotonic_name); - let mono_ty = quote!(core::mem::MaybeUninit<#m>); + let mono_ty = quote!(Option<#m>); items.push(quote!( #[doc = #doc] - static mut #mono: #mono_ty = core::mem::MaybeUninit::uninit(); + static mut #mono: #mono_ty = None; )); } @@ -122,10 +122,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea #[no_mangle] #[allow(non_snake_case)] unsafe fn #bound_interrupt() { - while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue( - || #disable_isr, - &mut *#app_path::#m_ident.as_mut_ptr(), - )) + + while let Some((task, index)) = rtic::export::interrupt::free(|_| + if let Some(mono) = #app_path::#m_ident.as_mut() { + #tq.dequeue(|| #disable_isr, mono) + } else { + // We can only use the timer queue if `init` has returned, and it + // writes the `Some(monotonic)` we are accessing here. + core::hint::unreachable_unchecked() + }) { match task { #(#arms)* |