From 1f4561b63d1bca64675373385ed8292dcd23e7e6 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 9 May 2025 21:27:18 +0100 Subject: [PATCH] Don't lint against named labels in `naked_asm!` Naked functions are allowed to define global labels, just like `global_asm!`. --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_lint/src/builtin.rs | 11 +++++++- tests/ui/asm/named-asm-labels.rs | 26 +++++++++++++++---- tests/ui/asm/named-asm-labels.stderr | 39 +++++++++++----------------- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 97e070958751a..984b280e81b5a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2849,7 +2849,7 @@ impl InlineAsmOperand { } } -#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable)] +#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)] pub enum AsmMacro { /// The `asm!` macro Asm, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index eb4c3703dbd6f..bf128b5914f0f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2870,7 +2870,7 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels { if let hir::Expr { kind: hir::ExprKind::InlineAsm(hir::InlineAsm { - asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm, + asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm), template_strs, options, .. @@ -2878,6 +2878,15 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels { .. } = expr { + // Non-generic naked functions are allowed to define arbitrary + // labels. + if *asm_macro == AsmMacro::NakedAsm { + let def_id = expr.hir_id.owner.def_id; + if !cx.tcx.generics_of(def_id).requires_monomorphization(cx.tcx) { + return; + } + } + // asm with `options(raw)` does not do replacement with `{` and `}`. let raw = options.contains(InlineAsmOptions::RAW); diff --git a/tests/ui/asm/named-asm-labels.rs b/tests/ui/asm/named-asm-labels.rs index 996fb82a944f2..e78553fd775f0 100644 --- a/tests/ui/asm/named-asm-labels.rs +++ b/tests/ui/asm/named-asm-labels.rs @@ -171,12 +171,10 @@ fn main() { } } -// Trigger on naked fns too, even though they can't be inlined, reusing a -// label or LTO can cause labels to break +// Don't trigger on naked functions. #[unsafe(naked)] pub extern "C" fn foo() -> i32 { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) - //~^ ERROR avoid using named labels } // Make sure that non-naked attributes *do* still let the lint happen @@ -190,7 +188,18 @@ pub extern "C" fn bar() { pub extern "C" fn aaa() { fn _local() {} - naked_asm!(".Laaa: nop; ret;") //~ ERROR avoid using named labels + naked_asm!(".Laaa: nop; ret;") +} + +#[unsafe(naked)] +pub extern "C" fn bbb<'a>(a: &'a u32) { + naked_asm!(".Lbbb: nop; ret;") +} + +#[unsafe(naked)] +pub extern "C" fn ccc(a: &T) { + naked_asm!(".Lccc: nop; ret;") + //~^ ERROR avoid using named labels } pub fn normal() { @@ -200,7 +209,7 @@ pub fn normal() { pub extern "C" fn bbb() { fn _very_local() {} - naked_asm!(".Lbbb: nop; ret;") //~ ERROR avoid using named labels + naked_asm!(".Lbbb: nop; ret;") } fn _local2() {} @@ -230,3 +239,10 @@ fn closures() { // Don't trigger on global asm global_asm!("aaaaaaaa: nop"); + +trait Foo { + #[unsafe(naked)] + extern "C" fn bbb<'a>(a: &'a u32) { + naked_asm!(".Lbbb: nop; ret;") //~ ERROR avoid using named labels + } +} diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr index cd7e7a08c1d29..9ba9e14de3aeb 100644 --- a/tests/ui/asm/named-asm-labels.stderr +++ b/tests/ui/asm/named-asm-labels.stderr @@ -475,16 +475,7 @@ LL | #[warn(named_asm_labels)] | ^^^^^^^^^^^^^^^^ error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:178:17 - | -LL | naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) - | ^^^^^ - | - = help: only local labels of the form `:` should be used in inline asm - = note: see the asm section of Rust By Example for more information - -error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:185:20 + --> $DIR/named-asm-labels.rs:183:20 | LL | unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } | ^^^^^ @@ -493,49 +484,49 @@ LL | unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noret = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:193:17 + --> $DIR/named-asm-labels.rs:201:17 | -LL | naked_asm!(".Laaa: nop; ret;") +LL | naked_asm!(".Lccc: nop; ret;") | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:203:21 + --> $DIR/named-asm-labels.rs:221:15 | -LL | naked_asm!(".Lbbb: nop; ret;") - | ^^^^^ +LL | asm!("closure1: nop"); + | ^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:212:15 + --> $DIR/named-asm-labels.rs:225:15 | -LL | asm!("closure1: nop"); +LL | asm!("closure2: nop"); | ^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:216:15 + --> $DIR/named-asm-labels.rs:235:19 | -LL | asm!("closure2: nop"); - | ^^^^^^^^ +LL | asm!("closure3: nop"); + | ^^^^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information error: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:226:19 + --> $DIR/named-asm-labels.rs:246:21 | -LL | asm!("closure3: nop"); - | ^^^^^^^^ +LL | naked_asm!(".Lbbb: nop; ret;") + | ^^^^^ | = help: only local labels of the form `:` should be used in inline asm = note: see the asm section of Rust By Example for more information -error: aborting due to 56 previous errors; 1 warning emitted +error: aborting due to 55 previous errors; 1 warning emitted