rust/tests/ui/asm/named-asm-labels.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

235 lines
7.3 KiB
Rust
Raw Normal View History

//@ needs-asm-support
//@ ignore-nvptx64
//@ ignore-spirv
2021-07-21 17:01:05 -05:00
2021-08-19 15:34:01 -05:00
// Tests that the use of named labels in the `asm!` macro are linted against
// except for in `#[naked]` fns.
// Using a named label is incorrect as per the RFC because for most cases
// the compiler cannot ensure that inline asm is emitted exactly once per
// codegen unit (except for naked fns) and so the label could be duplicated
// which causes less readable LLVM errors and in the worst cases causes ICEs
// or segfaults based on system dependent behavior and codegen flags.
2024-08-10 11:13:03 -05:00
#![feature(naked_functions)]
use std::arch::{asm, global_asm, naked_asm};
2021-07-20 15:35:26 -05:00
2021-07-21 17:01:05 -05:00
#[no_mangle]
pub static FOO: usize = 42;
2021-07-20 15:35:26 -05:00
fn main() {
unsafe {
// Basic usage
2021-07-29 17:56:31 -05:00
asm!("bar: nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// No following asm
2021-07-29 17:56:31 -05:00
asm!("abcd:"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Multiple labels on one line
asm!("foo: bar1: nop");
2021-07-29 17:56:31 -05:00
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Multiple lines
2021-07-29 17:56:31 -05:00
asm!("foo1: nop", "nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
asm!("foo2: foo3: nop", "nop");
2021-07-29 17:56:31 -05:00
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
2021-07-29 17:56:31 -05:00
asm!("nop", "foo4: nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
asm!("foo5: nop", "foo6: nop");
2021-07-29 17:56:31 -05:00
//~^ ERROR avoid using named labels
//~| ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Statement separator
asm!("foo7: nop; foo8: nop");
2021-07-29 17:56:31 -05:00
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
2021-07-29 17:56:31 -05:00
asm!("foo9: nop; nop"); //~ ERROR avoid using named labels
asm!("nop; foo10: nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Escaped newline
asm!("bar2: nop\n bar3: nop");
2021-07-29 17:56:31 -05:00
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
2021-07-29 17:56:31 -05:00
asm!("bar4: nop\n nop"); //~ ERROR avoid using named labels
asm!("nop\n bar5: nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
asm!("nop\n bar6: bar7: nop");
2021-07-29 17:56:31 -05:00
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Raw strings
asm!(
r"
blah2: nop
blah3: nop
"
);
2021-07-29 17:56:31 -05:00
//~^^^^ ERROR avoid using named labels
//~^^^^ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
asm!(
r###"
nop
nop ; blah4: nop
"###
);
2021-07-29 17:56:31 -05:00
//~^^^ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Non-labels
// should not trigger lint, but may be invalid asm
asm!("ab cd: nop");
// `blah:` does not trigger because labels need to be at the start
// of the statement, and there was already a non-label
asm!("1bar: blah: nop");
2021-07-20 15:35:26 -05:00
// Only `blah1:` should trigger
2021-07-29 17:56:31 -05:00
asm!("blah1: 2bar: nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Duplicate labels
asm!("def: def: nop");
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
asm!("def: nop\ndef: nop");
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
asm!("def: nop; def: nop");
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Trying to break parsing
asm!(":");
asm!("\n:\n");
asm!("::::");
// 0x3A is a ':'
2021-07-29 17:56:31 -05:00
asm!("fooo\u{003A} nop"); //~ ERROR avoid using named labels
asm!("foooo\x3A nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// 0x0A is a newline
2021-07-29 17:56:31 -05:00
asm!("fooooo:\u{000A} nop"); //~ ERROR avoid using named labels
asm!("foooooo:\x0A nop"); //~ ERROR avoid using named labels
2021-07-20 15:35:26 -05:00
// Intentionally breaking span finding
// equivalent to "ABC: nop"
2021-07-29 17:56:31 -05:00
asm!("\x41\x42\x43\x3A\x20\x6E\x6F\x70"); //~ ERROR avoid using named labels
// Non-label colons - should pass
asm!("mov rax, qword ptr fs:[0]");
// Comments
asm!(
r"
ab: nop // ab: does foo
// cd: nop
"
);
2021-07-29 17:56:31 -05:00
//~^^^^ ERROR avoid using named labels
2021-07-21 17:01:05 -05:00
// Tests usage of colons in non-label positions
asm!(":lo12:FOO"); // this is apparently valid aarch64
2024-08-10 11:13:03 -05:00
2021-07-21 17:01:05 -05:00
// is there an example that is valid x86 for this test?
asm!(":bbb nop");
// non-ascii characters are not allowed in labels, so should not trigger the lint
asm!("Ù: nop");
asm!("testÙ: nop");
asm!("_Ù_: nop");
// Format arguments should be conservatively assumed to be valid characters in labels
// Would emit `test_rax:` or similar
#[allow(asm_sub_register)]
{
asm!("test_{}: nop", in(reg) 10); //~ ERROR avoid using named labels
}
asm!("test_{}: nop", const 10); //~ ERROR avoid using named labels
asm!("test_{}: nop", sym main); //~ ERROR avoid using named labels
asm!("{}_test: nop", const 10); //~ ERROR avoid using named labels
asm!("test_{}_test: nop", const 10); //~ ERROR avoid using named labels
asm!("{}: nop", const 10); //~ ERROR avoid using named labels
asm!("{uwu}: nop", uwu = const 10); //~ ERROR avoid using named labels
asm!("{0}: nop", const 10); //~ ERROR avoid using named labels
asm!("{1}: nop", "/* {0} */", const 10, const 20); //~ ERROR avoid using named labels
// Test include_str in asm
asm!(include_str!("named-asm-labels.s"));
//~^ ERROR avoid using named labels
//~^^ ERROR avoid using named labels
//~^^^ ERROR avoid using named labels
//~^^^^ ERROR avoid using named labels
// Test allowing or warning on the lint instead
#[allow(named_asm_labels)]
{
asm!("allowed: nop"); // Should not emit anything
}
#[warn(named_asm_labels)]
{
2021-07-29 17:56:31 -05:00
asm!("warned: nop"); //~ WARNING avoid using named labels
}
2021-07-20 15:35:26 -05:00
}
}
2021-08-19 15:34:01 -05:00
// Trigger on naked fns too, even though they can't be inlined, reusing a
// label or LTO can cause labels to break
#[naked]
pub extern "C" fn foo() -> i32 {
unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
2024-08-10 11:13:03 -05:00
//~^ ERROR avoid using named labels
2021-08-19 15:34:01 -05:00
}
// Make sure that non-naked attributes *do* still let the lint happen
#[no_mangle]
pub extern "C" fn bar() {
unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
//~^ ERROR avoid using named labels
}
#[naked]
pub extern "C" fn aaa() {
fn _local() {}
unsafe { naked_asm!(".Laaa: nop; ret;") } //~ ERROR avoid using named labels
2021-08-19 15:34:01 -05:00
}
pub fn normal() {
fn _local1() {}
#[naked]
pub extern "C" fn bbb() {
fn _very_local() {}
unsafe { naked_asm!(".Lbbb: nop; ret;") } //~ ERROR avoid using named labels
2021-08-19 15:34:01 -05:00
}
fn _local2() {}
}
// Make sure that the lint happens within closures
fn closures() {
|| unsafe {
asm!("closure1: nop"); //~ ERROR avoid using named labels
};
move || unsafe {
asm!("closure2: nop"); //~ ERROR avoid using named labels
};
|| {
#[naked]
unsafe extern "C" fn _nested() {
naked_asm!("ret;");
2021-08-19 15:34:01 -05:00
}
unsafe {
asm!("closure3: nop"); //~ ERROR avoid using named labels
}
};
}
2021-07-20 15:35:26 -05:00
// Don't trigger on global asm
global_asm!("aaaaaaaa: nop");