diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b2d8881e3f6f2..e020ea04499ee 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2784,7 +2784,7 @@ impl InlineAsmOperand { } } -#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, 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 172f3372483ae..14d72c1331e96 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2874,7 +2874,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, .. @@ -2882,6 +2882,20 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels { .. } = expr { + // Non-generic naked functions are allowed to define arbitrary + // labels. + if *asm_macro == AsmMacro::NakedAsm { + let mono = cx.generics.is_none_or(|generics| { + generics + .params + .iter() + .all(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) + }); + if mono { + 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..4b9300adf54a2 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() {} diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr index cd7e7a08c1d29..fa7aa75055e5c 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,25 +484,16 @@ 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 - | -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: avoid using named labels in inline assembly - --> $DIR/named-asm-labels.rs:212:15 + --> $DIR/named-asm-labels.rs:221:15 | LL | asm!("closure1: nop"); | ^^^^^^^^ @@ -520,7 +502,7 @@ LL | asm!("closure1: nop"); = 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:225:15 | LL | asm!("closure2: nop"); | ^^^^^^^^ @@ -529,7 +511,7 @@ LL | asm!("closure2: nop"); = 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:235:19 | LL | asm!("closure3: nop"); | ^^^^^^^^ @@ -537,5 +519,5 @@ 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: aborting due to 56 previous errors; 1 warning emitted +error: aborting due to 54 previous errors; 1 warning emitted