diff options
author | 2020-08-23 21:57:08 +0200 | |
---|---|---|
committer | 2020-08-23 21:57:08 +0200 | |
commit | 679d42223fe79759bc634675694c46ae8ba0ce62 (patch) | |
tree | 141c8540c6e2b90ddd1d8b46ca284b6422103289 /cortex-m-rt/macros | |
parent | 972f60f50e48c07fda40d2b853558c7db9b5a4ff (diff) | |
download | cortex-m-679d42223fe79759bc634675694c46ae8ba0ce62.tar.gz cortex-m-679d42223fe79759bc634675694c46ae8ba0ce62.tar.zst cortex-m-679d42223fe79759bc634675694c46ae8ba0ce62.zip |
Make it unsafe to define NMI handlers
Diffstat (limited to 'cortex-m-rt/macros')
-rw-r--r-- | cortex-m-rt/macros/src/lib.rs | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 3c532c0..7e54a5c 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -113,6 +113,14 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { .into() } +#[derive(Debug, PartialEq)] +enum Exception { + DefaultHandler, + HardFault, + NonMaskableInt, + Other, +} + #[proc_macro_attribute] pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let mut f = parse_macro_input!(input as ItemFn); @@ -130,20 +138,15 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let fspan = f.span(); let ident = f.sig.ident.clone(); - enum Exception { - DefaultHandler, - HardFault, - Other, - } - let ident_s = ident.to_string(); let exn = match &*ident_s { "DefaultHandler" => Exception::DefaultHandler, "HardFault" => Exception::HardFault, + "NonMaskableInt" => Exception::NonMaskableInt, // NOTE that at this point we don't check if the exception is available on the target (e.g. // MemoryManagement is not available on Cortex-M0) - "NonMaskableInt" | "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" - | "SVCall" | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other, + "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall" + | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other, _ => { return parse::Error::new(ident.span(), "This is not a valid exception name") .to_compile_error() @@ -151,7 +154,22 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { } }; - // XXX should we blacklist other attributes? + if f.sig.unsafety.is_none() { + match exn { + Exception::DefaultHandler | Exception::HardFault | Exception::NonMaskableInt => { + // These are unsafe to define. + let name = if exn == Exception::DefaultHandler { + format!("`DefaultHandler`") + } else { + format!("`{:?}` handler", exn) + }; + return parse::Error::new(ident.span(), format_args!("defining a {} is unsafe and requires an `unsafe fn` (see the cortex-m-rt docs)", name)) + .to_compile_error() + .into(); + } + Exception::Other => {} + } + } match exn { Exception::DefaultHandler => { @@ -174,7 +192,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { if !valid_signature { return parse::Error::new( fspan, - "`DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`", + "`DefaultHandler` must have signature `unsafe fn(i16) [-> !]`", ) .to_compile_error() .into(); @@ -231,7 +249,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { if !valid_signature { return parse::Error::new( fspan, - "`HardFault` handler must have signature `[unsafe] fn(&ExceptionFrame) -> !`", + "`HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`", ) .to_compile_error() .into(); @@ -257,7 +275,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { ) .into() } - Exception::Other => { + Exception::NonMaskableInt | Exception::Other => { let valid_signature = f.sig.constness.is_none() && f.vis == Visibility::Inherited && f.sig.abi.is_none() |