aboutsummaryrefslogtreecommitdiff
path: root/cortex-m-rt/tests
diff options
context:
space:
mode:
Diffstat (limited to 'cortex-m-rt/tests')
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs16
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs18
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-hidden.rs22
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-twice.rs22
-rw-r--r--cortex-m-rt/tests/compile-fail/duplicate-static.rs32
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-args.rs12
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs11
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs11
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs13
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-hidden.rs19
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-soundness.rs26
-rw-r--r--cortex-m-rt/tests/compile-fail/entry-twice.rs17
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-args.rs15
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs16
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs18
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-hidden.rs22
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs24
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-soundness.rs29
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-twice.rs22
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-v8only.rs16
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs18
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs24
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-twice.rs26
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-args.rs20
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-bad-signature-1.rs21
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-bad-signature-2.rs23
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-invalid.rs22
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-not-reexported.rs15
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-soundness.rs34
-rw-r--r--cortex-m-rt/tests/compile-fail/interrupt-twice.rs31
-rw-r--r--cortex-m-rt/tests/compile-fail/non-static-resource.rs44
-rw-r--r--cortex-m-rt/tests/compile-fail/pre-init-args.rs15
-rw-r--r--cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs16
-rw-r--r--cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs16
-rw-r--r--cortex-m-rt/tests/compile-fail/pre-init-hidden.rs23
-rw-r--r--cortex-m-rt/tests/compile-fail/pre-init-twice.rs18
-rw-r--r--cortex-m-rt/tests/compile-fail/unsafe-init-static.rs45
-rw-r--r--cortex-m-rt/tests/compile-fail/whitelist-1.rs32
-rw-r--r--cortex-m-rt/tests/compile-fail/whitelist-2.rs32
-rw-r--r--cortex-m-rt/tests/compile-fail/whitelist-3.rs32
-rw-r--r--cortex-m-rt/tests/compile-fail/whitelist-4.rs32
-rw-r--r--cortex-m-rt/tests/compile-fail/whitelist-double-attr.rs13
-rw-r--r--cortex-m-rt/tests/compiletest.rs22
43 files changed, 955 insertions, 0 deletions
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
new file mode 100644
index 0000000..b590883
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
@@ -0,0 +1,16 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+unsafe fn DefaultHandler(_irqn: i16, undef: u32) {}
+//~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
new file mode 100644
index 0000000..0dadd6a
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
@@ -0,0 +1,18 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+unsafe fn DefaultHandler(_irqn: i16) -> u32 {
+ //~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
+ 0
+}
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
new file mode 100644
index 0000000..c658e2b
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
@@ -0,0 +1,22 @@
+// ignore-test :sadface: it's not possible to prevent this user error at compile time
+// see rust-lang/rust#53975 for details
+
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+mod hidden {
+ use cortex_m_rt::exception;
+
+ #[exception]
+ unsafe fn DefaultHandler(_irqn: i16) {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-twice.rs b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
new file mode 100644
index 0000000..bbf2edd
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
@@ -0,0 +1,22 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+unsafe fn DefaultHandler(_irqn: i16) {}
+
+pub mod reachable {
+ use cortex_m_rt::exception;
+
+ #[exception] //~ ERROR symbol `DefaultHandler` is already defined
+ unsafe fn DefaultHandler(_irqn: i16) {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/duplicate-static.rs b/cortex-m-rt/tests/compile-fail/duplicate-static.rs
new file mode 100644
index 0000000..eeb884f
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/duplicate-static.rs
@@ -0,0 +1,32 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt};
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ UART0,
+}
+
+#[entry]
+fn foo() -> ! {
+ static mut X: u32 = 0;
+ static mut X: i32 = 0; //~ ERROR the name `X` is defined multiple times
+
+ loop {}
+}
+
+#[exception]
+fn SVCall() {
+ static mut X: u32 = 0;
+ static mut X: i32 = 0; //~ ERROR the name `X` is defined multiple times
+}
+
+#[interrupt]
+fn UART0() {
+ static mut X: u32 = 0;
+ static mut X: i32 = 0; //~ ERROR the name `X` is defined multiple times
+}
diff --git a/cortex-m-rt/tests/compile-fail/entry-args.rs b/cortex-m-rt/tests/compile-fail/entry-args.rs
new file mode 100644
index 0000000..5f0b837
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-args.rs
@@ -0,0 +1,12 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::entry;
+
+#[entry(foo)] //~ ERROR This attribute accepts no arguments
+fn foo() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs
new file mode 100644
index 0000000..1ed3649
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-bad-signature-1.rs
@@ -0,0 +1,11 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::entry;
+
+#[entry]
+fn foo() {}
+//~^ ERROR `#[entry]` function must have signature `[unsafe] fn() -> !`
diff --git a/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs
new file mode 100644
index 0000000..359444c
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-bad-signature-2.rs
@@ -0,0 +1,11 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::entry;
+
+#[entry]
+fn foo(undef: i32) -> ! {}
+//~^ ERROR `#[entry]` function must have signature `[unsafe] fn() -> !`
diff --git a/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs b/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs
new file mode 100644
index 0000000..048b0e6
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-bad-signature-3.rs
@@ -0,0 +1,13 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::entry;
+
+#[entry]
+extern "C" fn foo() -> ! {
+ //~^ ERROR `#[entry]` function must have signature `[unsafe] fn() -> !`
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/entry-hidden.rs b/cortex-m-rt/tests/compile-fail/entry-hidden.rs
new file mode 100644
index 0000000..836db0d
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-hidden.rs
@@ -0,0 +1,19 @@
+// ignore-test :sadface: it's not possible to prevent this user error at compile time
+// see rust-lang/rust#53975 for details
+
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+mod hidden {
+ use cortex_m_rt::entry;
+
+ // this function needs to be "reachable" (all modules between it and the crate root must be
+ // `pub`) or linking will fail
+ #[entry]
+ fn foo() -> ! { //~ ERROR function is never used
+ loop {}
+ }
+}
diff --git a/cortex-m-rt/tests/compile-fail/entry-soundness.rs b/cortex-m-rt/tests/compile-fail/entry-soundness.rs
new file mode 100644
index 0000000..9fc8ec1
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-soundness.rs
@@ -0,0 +1,26 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ static mut COUNT: u64 = 0;
+
+ loop {
+ if *COUNT % 2 == 0 {
+ *COUNT += 1;
+ } else {
+ *COUNT *= 2;
+ }
+ }
+}
+
+#[exception]
+fn SysTick() {
+ // If this was allowed it would lead to a data race as `SysTick` can preempt `foo`
+ foo(); //~ ERROR cannot find function `foo` in this scope
+}
diff --git a/cortex-m-rt/tests/compile-fail/entry-twice.rs b/cortex-m-rt/tests/compile-fail/entry-twice.rs
new file mode 100644
index 0000000..757083a
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/entry-twice.rs
@@ -0,0 +1,17 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::entry;
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[entry] //~ ERROR symbol `main` is already defined
+fn bar() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/exception-args.rs b/cortex-m-rt/tests/compile-fail/exception-args.rs
new file mode 100644
index 0000000..518ac03
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-args.rs
@@ -0,0 +1,15 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception(SysTick)] //~ ERROR This attribute accepts no arguments
+fn SysTick() {}
diff --git a/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs
new file mode 100644
index 0000000..2a046c3
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-bad-signature-1.rs
@@ -0,0 +1,16 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn SysTick(undef: u32) {}
+//~^ ERROR `#[exception]` handlers other than `DefaultHandler` and `HardFault` must have signature `[unsafe] fn() [-> !]`
diff --git a/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs
new file mode 100644
index 0000000..d2fb210
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-bad-signature-2.rs
@@ -0,0 +1,18 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn SysTick() -> u32 {
+ //~^ ERROR `#[exception]` handlers other than `DefaultHandler` and `HardFault` must have signature `[unsafe] fn() [-> !]`
+ 0
+}
diff --git a/cortex-m-rt/tests/compile-fail/exception-hidden.rs b/cortex-m-rt/tests/compile-fail/exception-hidden.rs
new file mode 100644
index 0000000..6f57089
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-hidden.rs
@@ -0,0 +1,22 @@
+// ignore-test :sadface: it's not possible to prevent this user error at compile time
+// see rust-lang/rust#53975 for details
+
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+mod hidden {
+ use cortex_m_rt::exception;
+
+ #[exception]
+ fn SysTick() {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs b/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs
new file mode 100644
index 0000000..f5de2f8
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs
@@ -0,0 +1,24 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn DefaultHandler(_irq: i16) {}
+//~^ ERROR defining a `DefaultHandler` is unsafe and requires an `unsafe fn`
+
+#[exception]
+fn HardFault() {}
+//~^ ERROR defining a `HardFault` handler is unsafe and requires an `unsafe fn`
+
+#[exception]
+fn NonMaskableInt() {}
+//~^ ERROR defining a `NonMaskableInt` handler is unsafe and requires an `unsafe fn`
diff --git a/cortex-m-rt/tests/compile-fail/exception-soundness.rs b/cortex-m-rt/tests/compile-fail/exception-soundness.rs
new file mode 100644
index 0000000..9a1e10b
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-soundness.rs
@@ -0,0 +1,29 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn SysTick() {
+ static mut COUNT: u64 = 0;
+
+ if *COUNT % 2 == 0 {
+ *COUNT += 1;
+ } else {
+ *COUNT *= 2;
+ }
+}
+
+#[exception]
+fn SVCall() {
+ // If this was allowed it would lead to a data race as `SVCall` could preempt `SysTick`
+ SysTick(); //~ ERROR cannot find function, tuple struct or tuple variant `SysTick` in this scope [E0425]
+}
diff --git a/cortex-m-rt/tests/compile-fail/exception-twice.rs b/cortex-m-rt/tests/compile-fail/exception-twice.rs
new file mode 100644
index 0000000..aabbe5a
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-twice.rs
@@ -0,0 +1,22 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn SysTick() {}
+
+pub mod reachable {
+ use cortex_m_rt::exception;
+
+ #[exception] //~ ERROR symbol `SysTick` is already defined
+ fn SysTick() {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/exception-v8only.rs b/cortex-m-rt/tests/compile-fail/exception-v8only.rs
new file mode 100644
index 0000000..d54f706
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-v8only.rs
@@ -0,0 +1,16 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn SecureFault() {}
+//~^ ERROR no variant or associated item named `SecureFault`
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
new file mode 100644
index 0000000..11b53dc
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
@@ -0,0 +1,18 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, ExceptionFrame};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+unsafe fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
+ //~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs b/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs
new file mode 100644
index 0000000..956310b
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-hidden.rs
@@ -0,0 +1,24 @@
+// ignore-test :sadface: it's not possible to prevent this user error at compile time
+// see rust-lang/rust#53975 for details
+
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, ExceptionFrame};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+mod hidden {
+ use cortex_m_rt::{exception, ExceptionFrame};
+
+ #[exception]
+ fn HardFault(_ef: &ExceptionFrame) -> ! {
+ loop {}
+ }
+}
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
new file mode 100644
index 0000000..03b79a5
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
@@ -0,0 +1,26 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, ExceptionFrame};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+ loop {}
+}
+
+pub mod reachable {
+ use cortex_m_rt::{exception, ExceptionFrame};
+
+ #[exception] //~ ERROR symbol `HardFault` is already defined
+ unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
+ loop {}
+ }
+}
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-args.rs b/cortex-m-rt/tests/compile-fail/interrupt-args.rs
new file mode 100644
index 0000000..1e06ec2
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-args.rs
@@ -0,0 +1,20 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+}
+
+#[interrupt(true)] //~ ERROR This attribute accepts no arguments
+fn USART1() {}
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/interrupt-bad-signature-1.rs
new file mode 100644
index 0000000..bd5ff9f
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-bad-signature-1.rs
@@ -0,0 +1,21 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+}
+
+#[interrupt]
+fn USART1(undef: i32) {}
+//~^ ERROR `#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/interrupt-bad-signature-2.rs
new file mode 100644
index 0000000..56db222
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-bad-signature-2.rs
@@ -0,0 +1,23 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+}
+
+#[interrupt]
+fn USART1() -> i32 {
+ //~^ ERROR `#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`
+ 0
+}
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-invalid.rs b/cortex-m-rt/tests/compile-fail/interrupt-invalid.rs
new file mode 100644
index 0000000..f2ec718
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-invalid.rs
@@ -0,0 +1,22 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn entry() -> ! {
+ loop {}
+}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+}
+
+// NOTE this looks a bit better when using a device crate:
+// "no variant named `foo` found for type `stm32f30x::Interrupt` in the current scope"
+#[interrupt]
+fn foo() {} //~ ERROR no variant or associated item named `foo` found for enum `interrupt` in the current scope [E0599]
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-not-reexported.rs b/cortex-m-rt/tests/compile-fail/interrupt-not-reexported.rs
new file mode 100644
index 0000000..6a1dd6e
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-not-reexported.rs
@@ -0,0 +1,15 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[interrupt] //~ ERROR failed to resolve: use of undeclared crate or module `interrupt`
+fn USART1() {}
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-soundness.rs b/cortex-m-rt/tests/compile-fail/interrupt-soundness.rs
new file mode 100644
index 0000000..faf737d
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-soundness.rs
@@ -0,0 +1,34 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+ USART2,
+}
+
+#[interrupt]
+fn USART1() {
+ static mut COUNT: u64 = 0;
+
+ if *COUNT % 2 == 0 {
+ *COUNT += 1;
+ } else {
+ *COUNT *= 2;
+ }
+}
+
+#[interrupt]
+fn USART2() {
+ USART1(); //~ ERROR cannot find function, tuple struct or tuple variant `USART1` in this scope [E0425]
+}
diff --git a/cortex-m-rt/tests/compile-fail/interrupt-twice.rs b/cortex-m-rt/tests/compile-fail/interrupt-twice.rs
new file mode 100644
index 0000000..b59aea9
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/interrupt-twice.rs
@@ -0,0 +1,31 @@
+#![allow(non_camel_case_types)]
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, interrupt};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+enum interrupt {
+ USART1,
+}
+
+#[interrupt]
+fn USART1() {}
+
+pub mod reachable {
+ use cortex_m_rt::interrupt;
+
+ enum interrupt {
+ USART1,
+ }
+
+ #[interrupt] //~ ERROR symbol `USART1` is already defined
+ fn USART1() {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/non-static-resource.rs b/cortex-m-rt/tests/compile-fail/non-static-resource.rs
new file mode 100644
index 0000000..a603728
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/non-static-resource.rs
@@ -0,0 +1,44 @@
+//! Tests that no `&'static mut` to static mutable resources can be obtained, which would be
+//! unsound.
+//!
+//! Regression test for https://github.com/rust-embedded/cortex-m-rt/issues/212
+
+#![no_std]
+#![no_main]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt, ExceptionFrame};
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ UART0,
+}
+
+#[exception]
+fn SVCall() {
+ static mut STAT: u8 = 0;
+
+ let _stat: &'static mut u8 = STAT;
+ //~^ ERROR lifetime of reference outlives lifetime of borrowed content
+}
+
+#[interrupt]
+fn UART0() {
+ static mut STAT: u8 = 0;
+
+ let _stat: &'static mut u8 = STAT;
+ //~^ ERROR lifetime of reference outlives lifetime of borrowed content
+}
+
+#[entry]
+fn you_died_of_dis_entry() -> ! {
+ static mut STAT: u8 = 0;
+
+ // Allowed. This is sound for the entry point since it is only ever called once, and it makes
+ // resources far more useful.
+ let _stat: &'static mut u8 = STAT;
+
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/pre-init-args.rs b/cortex-m-rt/tests/compile-fail/pre-init-args.rs
new file mode 100644
index 0000000..9732589
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/pre-init-args.rs
@@ -0,0 +1,15 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, pre_init};
+
+#[pre_init(foo)] //~ ERROR This attribute accepts no arguments
+unsafe fn foo() {}
+
+#[entry]
+fn baz() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs
new file mode 100644
index 0000000..0c3c476
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-1.rs
@@ -0,0 +1,16 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, pre_init};
+
+#[pre_init]
+fn foo() {}
+//~^ ERROR `#[pre_init]` function must have signature `unsafe fn()`
+
+#[entry]
+fn bar() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs
new file mode 100644
index 0000000..f41d032
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/pre-init-bad-signature-2.rs
@@ -0,0 +1,16 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, pre_init};
+
+#[pre_init]
+unsafe fn foo(undef: i32) {}
+//~^ ERROR `#[pre_init]` function must have signature `unsafe fn()`
+
+#[entry]
+fn bar() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs b/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs
new file mode 100644
index 0000000..63ab90b
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/pre-init-hidden.rs
@@ -0,0 +1,23 @@
+// ignore-test :sadface: it's not possible to prevent this user error at compile time
+// see rust-lang/rust#53975 for details
+
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+mod hidden {
+ use cortex_m_rt::pre_init;
+
+ // this function needs to be "reachable" (all modules between it and the crate root must be
+ // `pub`) or the function will be ignored
+ #[entry]
+ unsafe fn pre_init() {} //~ ERROR function is never used
+}
+
+#[entry]
+fn foo() -> ! {
+ //~ ERROR function is never used
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/pre-init-twice.rs b/cortex-m-rt/tests/compile-fail/pre-init-twice.rs
new file mode 100644
index 0000000..74a3f6b
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/pre-init-twice.rs
@@ -0,0 +1,18 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, pre_init};
+
+#[pre_init]
+unsafe fn foo() {}
+
+#[pre_init] //~ ERROR symbol `__pre_init` is already defined
+unsafe fn bar() {}
+
+#[entry]
+fn baz() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
new file mode 100644
index 0000000..23105f1
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
@@ -0,0 +1,45 @@
+//! Makes sure that the expansion of the attributes doesn't put the resource initializer in an
+//! implicit `unsafe` block.
+
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt};
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ UART0,
+}
+
+const unsafe fn init() -> u32 { 0 }
+
+#[entry]
+fn foo() -> ! {
+ static mut X: u32 = init(); //~ ERROR requires unsafe
+
+ loop {}
+}
+
+#[exception]
+fn SVCall() {
+ static mut X: u32 = init(); //~ ERROR requires unsafe
+}
+
+#[exception]
+unsafe fn DefaultHandler(_irq: i16) {
+ static mut X: u32 = init(); //~ ERROR requires unsafe
+}
+
+#[exception]
+unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
+ static mut X: u32 = init(); //~ ERROR requires unsafe
+ loop {}
+}
+
+#[interrupt]
+fn UART0() {
+ static mut X: u32 = init(); //~ ERROR requires unsafe
+}
diff --git a/cortex-m-rt/tests/compile-fail/whitelist-1.rs b/cortex-m-rt/tests/compile-fail/whitelist-1.rs
new file mode 100644
index 0000000..9c5133b
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/whitelist-1.rs
@@ -0,0 +1,32 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt};
+
+#[inline] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[inline] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
+#[exception]
+fn SysTick() {}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+ USART2,
+}
+
+#[inline] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART1() {}
+
+#[cfg(feature = "device")]
+#[cfg_attr(feature = "device", inline)] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART2() {}
diff --git a/cortex-m-rt/tests/compile-fail/whitelist-2.rs b/cortex-m-rt/tests/compile-fail/whitelist-2.rs
new file mode 100644
index 0000000..086f909
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/whitelist-2.rs
@@ -0,0 +1,32 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt};
+
+#[export_name = "not_allowed"] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[export_name = "not_allowed"] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
+#[exception]
+fn SysTick() {}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+ USART2,
+}
+
+#[export_name = "not_allowed"] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART1() {}
+
+#[cfg(feature = "device")]
+#[cfg_attr(feature = "device", export_name = "not_allowed")] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART2() {}
diff --git a/cortex-m-rt/tests/compile-fail/whitelist-3.rs b/cortex-m-rt/tests/compile-fail/whitelist-3.rs
new file mode 100644
index 0000000..9e5fb33
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/whitelist-3.rs
@@ -0,0 +1,32 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt};
+
+#[no_mangle] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[no_mangle] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
+#[exception]
+fn SysTick() {}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+ USART2,
+}
+
+#[no_mangle] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART1() {}
+
+#[cfg(feature = "device")]
+#[cfg_attr(feature = "device", no_mangle)] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART2() {}
diff --git a/cortex-m-rt/tests/compile-fail/whitelist-4.rs b/cortex-m-rt/tests/compile-fail/whitelist-4.rs
new file mode 100644
index 0000000..95dad29
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/whitelist-4.rs
@@ -0,0 +1,32 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception, interrupt};
+
+#[must_use] //~ ERROR this attribute is not allowed on a cortex-m-rt entry point
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[must_use] //~ ERROR this attribute is not allowed on an exception handler controlled by cortex-m-rt
+#[exception]
+fn SysTick() {}
+
+#[allow(non_camel_case_types)]
+enum interrupt {
+ USART1,
+ USART2,
+}
+
+#[must_use] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART1() {}
+
+#[cfg(feature = "device")]
+#[cfg_attr(feature = "device", must_use)] //~ ERROR this attribute is not allowed on an interrupt handler controlled by cortex-m-rt
+#[interrupt]
+fn USART2() {}
diff --git a/cortex-m-rt/tests/compile-fail/whitelist-double-attr.rs b/cortex-m-rt/tests/compile-fail/whitelist-double-attr.rs
new file mode 100644
index 0000000..31da76a
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/whitelist-double-attr.rs
@@ -0,0 +1,13 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[exception]
+#[entry] //~ ERROR this attribute is not allowed on an exception handler
+fn SVCall() -> ! {
+ loop {}
+}
diff --git a/cortex-m-rt/tests/compiletest.rs b/cortex-m-rt/tests/compiletest.rs
new file mode 100644
index 0000000..cf63d22
--- /dev/null
+++ b/cortex-m-rt/tests/compiletest.rs
@@ -0,0 +1,22 @@
+extern crate compiletest_rs as compiletest;
+
+use std::path::PathBuf;
+
+fn run_mode(mode: &'static str) {
+ let mut config = compiletest::Config::default();
+
+ config.mode = mode.parse().expect("Invalid mode");
+ config.src_base = PathBuf::from(format!("tests/{}", mode));
+ config.target_rustcflags = Some(
+ "-L ../target/debug -L ../target/debug/deps -C panic=abort --cfg feature=\"device\""
+ .to_owned(),
+ );
+ config.clean_rmeta(); // If your tests import the parent crate, this helps with E0464
+
+ compiletest::run_tests(&config);
+}
+
+#[test]
+fn compile_test() {
+ run_mode("compile-fail");
+}