2021-06-24 09:01:49 -05:00
|
|
|
// needs-asm-support
|
2021-09-06 10:44:19 -05:00
|
|
|
// ignore-nvptx64
|
|
|
|
// ignore-spirv
|
|
|
|
// ignore-wasm32
|
|
|
|
|
2020-12-06 18:00:00 -06:00
|
|
|
#![feature(asm)]
|
|
|
|
#![feature(llvm_asm)]
|
|
|
|
#![feature(naked_functions)]
|
|
|
|
#![feature(or_patterns)]
|
2021-10-27 12:37:18 -05:00
|
|
|
#![feature(asm_const, asm_sym)]
|
2020-12-06 18:00:00 -06:00
|
|
|
#![crate_type = "lib"]
|
2021-07-29 12:45:13 -05:00
|
|
|
#![allow(deprecated)] // llvm_asm!
|
2020-12-06 18:00:00 -06:00
|
|
|
|
|
|
|
#[repr(C)]
|
2021-10-27 12:37:18 -05:00
|
|
|
pub struct P {
|
|
|
|
x: u8,
|
|
|
|
y: u16,
|
|
|
|
}
|
2020-12-06 18:00:00 -06:00
|
|
|
|
|
|
|
#[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 {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
a + 1
|
|
|
|
//~^ ERROR referencing function parameters is not allowed in naked functions
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
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
|
|
|
|
//~| WARN only `const` and `sym` operands are supported in naked functions
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
(|| a + 1)()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub unsafe extern "C" fn unsupported_operands() {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
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} */",
|
|
|
|
//~^ WARN asm in naked functions must use `noreturn` option
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
in(reg) a,
|
|
|
|
//~^ WARN only `const` and `sym` operands are supported in naked functions
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
inlateout(reg) b,
|
|
|
|
inout(reg) c,
|
|
|
|
lateout(reg) d,
|
|
|
|
out(reg) e,
|
|
|
|
const F,
|
|
|
|
sym G,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub extern "C" fn missing_assembly() {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub extern "C" fn too_many_asm_blocks() {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
asm!("");
|
|
|
|
//~^ WARN asm in naked functions must use `noreturn` option
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
asm!("");
|
|
|
|
//~^ WARN asm in naked functions must use `noreturn` option
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
asm!("");
|
|
|
|
//~^ WARN asm in naked functions must use `noreturn` option
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
|
|
|
|
#[naked]
|
|
|
|
pub extern "C" fn inner(y: usize) -> usize {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
*&y
|
|
|
|
//~^ ERROR referencing function parameters is not allowed in naked functions
|
|
|
|
}
|
|
|
|
inner
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
unsafe extern "C" fn llvm() -> ! {
|
|
|
|
//~^ WARN naked functions must contain a single asm block
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
llvm_asm!("");
|
|
|
|
//~^ WARN LLVM-style inline assembly is unsupported in naked functions
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
core::hint::unreachable_unchecked();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
unsafe extern "C" fn invalid_options() {
|
|
|
|
asm!("", options(nomem, preserves_flags, noreturn));
|
|
|
|
//~^ WARN asm options unsupported in naked functions: `nomem`, `preserves_flags`
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
unsafe extern "C" fn invalid_options_continued() {
|
|
|
|
asm!("", options(readonly, nostack), options(pure));
|
2021-07-29 04:15:50 -05:00
|
|
|
//~^ ERROR asm with the `pure` option must have at least one output
|
2020-12-06 18:00:00 -06:00
|
|
|
//~| WARN asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
//~| WARN asm in naked functions must use `noreturn` option
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub unsafe fn default_abi() {
|
|
|
|
//~^ WARN Rust ABI is unsupported in naked functions
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
2021-10-27 12:37:18 -05:00
|
|
|
pub unsafe fn rust_abi() {
|
2020-12-06 18:00:00 -06:00
|
|
|
//~^ WARN Rust ABI is unsupported in naked functions
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub extern "C" fn valid_a<T>() -> T {
|
2021-10-27 12:37:18 -05:00
|
|
|
unsafe {
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
2020-12-06 18:00:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub extern "C" fn valid_b() {
|
2021-10-27 12:37:18 -05:00
|
|
|
unsafe {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
2020-12-06 18:00:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[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));
|
|
|
|
}
|
2021-08-02 14:03:43 -05:00
|
|
|
|
|
|
|
#[naked]
|
|
|
|
pub unsafe extern "C" fn inline_none() {
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
#[inline]
|
|
|
|
//~^ WARN naked functions cannot be inlined
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
pub unsafe extern "C" fn inline_hint() {
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
#[inline(always)]
|
|
|
|
//~^ WARN naked functions cannot be inlined
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
pub unsafe extern "C" fn inline_always() {
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
#[inline(never)]
|
|
|
|
//~^ WARN naked functions cannot be inlined
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
pub unsafe extern "C" fn inline_never() {
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[naked]
|
|
|
|
#[inline]
|
|
|
|
//~^ WARN naked functions cannot be inlined
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
#[inline(always)]
|
|
|
|
//~^ WARN naked functions cannot be inlined
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
#[inline(never)]
|
|
|
|
//~^ WARN naked functions cannot be inlined
|
|
|
|
//~| WARN this was previously accepted
|
|
|
|
pub unsafe extern "C" fn inline_all() {
|
|
|
|
asm!("", options(noreturn));
|
|
|
|
}
|