diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 4ceefa17bcf3d..f2c2521ab43e4 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -332,6 +332,11 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { } } + // Don't run unused pass for #[naked] + if self.tcx.has_attr(def_id, sym::naked) { + return; + } + if let Some(captures) = maps.tcx.typeck(local_def_id).closure_min_captures.get(&def_id) { for &var_hir_id in captures.keys() { let var_name = maps.tcx.hir().name(var_hir_id); diff --git a/src/test/ui/asm/naked-functions-unused.rs b/src/test/ui/asm/naked-functions-unused.rs new file mode 100644 index 0000000000000..e1f2362bb6fd0 --- /dev/null +++ b/src/test/ui/asm/naked-functions-unused.rs @@ -0,0 +1,81 @@ +// only-x86_64 +#![deny(unused)] +#![feature(asm)] +#![feature(naked_functions)] +#![crate_type = "lib"] + +pub trait Trait { + extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize; + extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize; +} + +pub mod normal { + pub extern "sysv64" fn function(a: usize, b: usize) -> usize { + //~^ ERROR unused variable: `a` + //~| ERROR unused variable: `b` + unsafe { asm!("", options(noreturn)); } + } + + pub struct Normal; + + impl Normal { + pub extern "sysv64" fn associated(a: usize, b: usize) -> usize { + //~^ ERROR unused variable: `a` + //~| ERROR unused variable: `b` + unsafe { asm!("", options(noreturn)); } + } + + pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize { + //~^ ERROR unused variable: `a` + //~| ERROR unused variable: `b` + unsafe { asm!("", options(noreturn)); } + } + } + + impl super::Trait for Normal { + extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize { + //~^ ERROR unused variable: `a` + //~| ERROR unused variable: `b` + unsafe { asm!("", options(noreturn)); } + } + + extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize { + //~^ ERROR unused variable: `a` + //~| ERROR unused variable: `b` + unsafe { asm!("", options(noreturn)); } + } + } +} + +pub mod naked { + #[naked] + pub extern "sysv64" fn function(a: usize, b: usize) -> usize { + unsafe { asm!("", options(noreturn)); } + } + + pub struct Naked; + + impl Naked { + #[naked] + pub extern "sysv64" fn associated(a: usize, b: usize) -> usize { + unsafe { asm!("", options(noreturn)); } + } + + #[naked] + pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize { + unsafe { asm!("", options(noreturn)); } + } + } + + impl super::Trait for Naked { + #[naked] + extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize { + unsafe { asm!("", options(noreturn)); } + } + + #[naked] + extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize { + unsafe { asm!("", options(noreturn)); } + } + } +} diff --git a/src/test/ui/asm/naked-functions-unused.stderr b/src/test/ui/asm/naked-functions-unused.stderr new file mode 100644 index 0000000000000..840353366b670 --- /dev/null +++ b/src/test/ui/asm/naked-functions-unused.stderr @@ -0,0 +1,69 @@ +error: unused variable: `a` + --> $DIR/naked-functions-unused.rs:13:37 + | +LL | pub extern "sysv64" fn function(a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/naked-functions-unused.rs:2:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` + +error: unused variable: `b` + --> $DIR/naked-functions-unused.rs:13:47 + | +LL | pub extern "sysv64" fn function(a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/naked-functions-unused.rs:22:43 + | +LL | pub extern "sysv64" fn associated(a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/naked-functions-unused.rs:22:53 + | +LL | pub extern "sysv64" fn associated(a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/naked-functions-unused.rs:28:46 + | +LL | pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/naked-functions-unused.rs:28:56 + | +LL | pub extern "sysv64" fn method(&self, a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/naked-functions-unused.rs:36:45 + | +LL | extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/naked-functions-unused.rs:36:55 + | +LL | extern "sysv64" fn trait_associated(a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `a` + --> $DIR/naked-functions-unused.rs:42:48 + | +LL | extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_a` + +error: unused variable: `b` + --> $DIR/naked-functions-unused.rs:42:58 + | +LL | extern "sysv64" fn trait_method(&self, a: usize, b: usize) -> usize { + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: aborting due to 10 previous errors +