about summary refs log tree commit diff
path: root/tests/ui/asm/naked-functions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/asm/naked-functions.rs')
-rw-r--r--tests/ui/asm/naked-functions.rs218
1 files changed, 218 insertions, 0 deletions
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
new file mode 100644
index 00000000000..2f3716ca77f
--- /dev/null
+++ b/tests/ui/asm/naked-functions.rs
@@ -0,0 +1,218 @@
+// needs-asm-support
+// ignore-nvptx64
+// ignore-spirv
+// ignore-wasm32
+
+#![feature(naked_functions)]
+#![feature(asm_const, asm_unwind)]
+#![crate_type = "lib"]
+
+use std::arch::asm;
+
+#[repr(C)]
+pub struct P {
+    x: u8,
+    y: u16,
+}
+
+#[naked]
+pub unsafe extern "C" fn patterns(
+    mut a: u32,
+    //~^ ERROR patterns not allowed in naked function parameters
+    &b: &i32,
+    //~^ ERROR patterns not allowed in naked function parameters
+    (None | Some(_)): Option<std::ptr::NonNull<u8>>,
+    //~^ ERROR patterns not allowed in naked function parameters
+    P { x, y }: P,
+    //~^ ERROR patterns not allowed in naked function parameters
+) {
+    asm!("", options(noreturn))
+}
+
+#[naked]
+pub unsafe extern "C" fn inc(a: u32) -> u32 {
+    //~^ ERROR naked functions must contain a single asm block
+    a + 1
+    //~^ ERROR referencing function parameters is not allowed in naked functions
+}
+
+#[naked]
+#[allow(asm_sub_register)]
+pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
+    asm!("/* {0} */", in(reg) a, options(noreturn));
+    //~^ ERROR referencing function parameters is not allowed in naked functions
+    //~| ERROR only `const` and `sym` operands are supported in naked functions
+}
+
+#[naked]
+pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
+    //~^ ERROR naked functions must contain a single asm block
+    (|| a + 1)()
+}
+
+#[naked]
+pub unsafe extern "C" fn unsupported_operands() {
+    //~^ ERROR naked functions must contain a single asm block
+    let mut a = 0usize;
+    let mut b = 0usize;
+    let mut c = 0usize;
+    let mut d = 0usize;
+    let mut e = 0usize;
+    const F: usize = 0usize;
+    static G: usize = 0usize;
+    asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
+         //~^ ERROR asm in naked functions must use `noreturn` option
+         in(reg) a,
+         //~^ ERROR only `const` and `sym` operands are supported in naked functions
+         inlateout(reg) b,
+         inout(reg) c,
+         lateout(reg) d,
+         out(reg) e,
+         const F,
+         sym G,
+    );
+}
+
+#[naked]
+pub extern "C" fn missing_assembly() {
+    //~^ ERROR naked functions must contain a single asm block
+}
+
+#[naked]
+pub extern "C" fn too_many_asm_blocks() {
+    //~^ ERROR naked functions must contain a single asm block
+    asm!("");
+    //~^ ERROR asm in naked functions must use `noreturn` option
+    asm!("");
+    //~^ ERROR asm in naked functions must use `noreturn` option
+    asm!("");
+    //~^ ERROR asm in naked functions must use `noreturn` option
+    asm!("", options(noreturn));
+}
+
+pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
+    #[naked]
+    pub extern "C" fn inner(y: usize) -> usize {
+        //~^ ERROR naked functions must contain a single asm block
+        *&y
+        //~^ ERROR referencing function parameters is not allowed in naked functions
+    }
+    inner
+}
+
+#[naked]
+unsafe extern "C" fn invalid_options() {
+    asm!("", options(nomem, preserves_flags, noreturn));
+    //~^ ERROR asm options unsupported in naked functions: `nomem`, `preserves_flags`
+}
+
+#[naked]
+unsafe extern "C" fn invalid_options_continued() {
+    asm!("", options(readonly, nostack), options(pure));
+    //~^ ERROR asm with the `pure` option must have at least one output
+    //~| ERROR asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
+    //~| ERROR asm in naked functions must use `noreturn` option
+}
+
+#[naked]
+unsafe extern "C" fn invalid_may_unwind() {
+    asm!("", options(noreturn, may_unwind));
+    //~^ ERROR asm options unsupported in naked functions: `may_unwind`
+}
+
+#[naked]
+pub unsafe fn default_abi() {
+    //~^ WARN Rust ABI is unsupported in naked functions
+    asm!("", options(noreturn));
+}
+
+#[naked]
+pub unsafe fn rust_abi() {
+    //~^ WARN Rust ABI is unsupported in naked functions
+    asm!("", options(noreturn));
+}
+
+#[naked]
+pub extern "C" fn valid_a<T>() -> T {
+    unsafe {
+        asm!("", options(noreturn));
+    }
+}
+
+#[naked]
+pub extern "C" fn valid_b() {
+    unsafe {
+        {
+            {
+                asm!("", options(noreturn));
+            };
+        };
+    }
+}
+
+#[naked]
+pub unsafe extern "C" fn valid_c() {
+    asm!("", options(noreturn));
+}
+
+#[cfg(target_arch = "x86_64")]
+#[naked]
+pub unsafe extern "C" fn valid_att_syntax() {
+    asm!("", options(noreturn, att_syntax));
+}
+
+#[naked]
+pub unsafe extern "C" fn inline_none() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline]
+//~^ ERROR naked functions cannot be inlined
+pub unsafe extern "C" fn inline_hint() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline(always)]
+//~^ ERROR naked functions cannot be inlined
+pub unsafe extern "C" fn inline_always() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline(never)]
+//~^ ERROR naked functions cannot be inlined
+pub unsafe extern "C" fn inline_never() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+#[inline]
+//~^ ERROR naked functions cannot be inlined
+#[inline(always)]
+//~^ ERROR naked functions cannot be inlined
+#[inline(never)]
+//~^ ERROR naked functions cannot be inlined
+pub unsafe extern "C" fn inline_all() {
+    asm!("", options(noreturn));
+}
+
+#[naked]
+pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
+    compile_error!("this is a user specified error")
+    //~^ ERROR this is a user specified error
+}
+
+#[naked]
+pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
+    compile_error!("this is a user specified error");
+    //~^ ERROR this is a user specified error
+    asm!("", options(noreturn))
+}
+
+#[naked]
+pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
+    asm!(invalid_syntax)
+    //~^ ERROR asm template must be a string literal
+}