6 // Tests that the use of named labels in the `asm!` macro are linted against
7 // except for in `#[naked]` fns.
8 // Using a named label is incorrect as per the RFC because for most cases
9 // the compiler cannot ensure that inline asm is emitted exactly once per
10 // codegen unit (except for naked fns) and so the label could be duplicated
11 // which causes less readable LLVM errors and in the worst cases causes ICEs
12 // or segfaults based on system dependent behavior and codegen flags.
14 #![feature(naked_functions, asm_const)]
16 use std::arch::{asm, global_asm};
19 pub static FOO: usize = 42;
24 asm!("bar: nop"); //~ ERROR avoid using named labels
27 asm!("abcd:"); //~ ERROR avoid using named labels
29 // Multiple labels on one line
30 asm!("foo: bar1: nop");
31 //~^ ERROR avoid using named labels
34 asm!("foo1: nop", "nop"); //~ ERROR avoid using named labels
35 asm!("foo2: foo3: nop", "nop");
36 //~^ ERROR avoid using named labels
37 asm!("nop", "foo4: nop"); //~ ERROR avoid using named labels
38 asm!("foo5: nop", "foo6: nop");
39 //~^ ERROR avoid using named labels
40 //~| ERROR avoid using named labels
42 // Statement separator
43 asm!("foo7: nop; foo8: nop");
44 //~^ ERROR avoid using named labels
45 asm!("foo9: nop; nop"); //~ ERROR avoid using named labels
46 asm!("nop; foo10: nop"); //~ ERROR avoid using named labels
49 asm!("bar2: nop\n bar3: nop");
50 //~^ ERROR avoid using named labels
51 asm!("bar4: nop\n nop"); //~ ERROR avoid using named labels
52 asm!("nop\n bar5: nop"); //~ ERROR avoid using named labels
53 asm!("nop\n bar6: bar7: nop");
54 //~^ ERROR avoid using named labels
63 //~^^^^ ERROR avoid using named labels
71 //~^^^ ERROR avoid using named labels
74 // should not trigger lint, but may be invalid asm
77 // `blah:` does not trigger because labels need to be at the start
78 // of the statement, and there was already a non-label
79 asm!("1bar: blah: nop");
81 // Only `blah1:` should trigger
82 asm!("blah1: 2bar: nop"); //~ ERROR avoid using named labels
85 asm!("def: def: nop"); //~ ERROR avoid using named labels
86 asm!("def: nop\ndef: nop"); //~ ERROR avoid using named labels
87 asm!("def: nop; def: nop"); //~ ERROR avoid using named labels
89 // Trying to break parsing
95 asm!("fooo\u{003A} nop"); //~ ERROR avoid using named labels
96 asm!("foooo\x3A nop"); //~ ERROR avoid using named labels
99 asm!("fooooo:\u{000A} nop"); //~ ERROR avoid using named labels
100 asm!("foooooo:\x0A nop"); //~ ERROR avoid using named labels
102 // Intentionally breaking span finding
103 // equivalent to "ABC: nop"
104 asm!("\x41\x42\x43\x3A\x20\x6E\x6F\x70"); //~ ERROR avoid using named labels
106 // Non-label colons - should pass
107 asm!("mov rax, qword ptr fs:[0]");
112 ab: nop // ab: does foo
116 //~^^^^ ERROR avoid using named labels
118 // Tests usage of colons in non-label positions
119 asm!(":lo12:FOO"); // this is apparently valid aarch64
120 // is there an example that is valid x86 for this test?
123 // Test include_str in asm
124 asm!(include_str!("named-asm-labels.s")); //~ ERROR avoid using named labels
126 // Test allowing or warning on the lint instead
127 #[allow(named_asm_labels)]
129 asm!("allowed: nop"); // Should not emit anything
132 #[warn(named_asm_labels)]
134 asm!("warned: nop"); //~ WARNING avoid using named labels
139 // Trigger on naked fns too, even though they can't be inlined, reusing a
140 // label or LTO can cause labels to break
142 pub extern "C" fn foo() -> i32 {
143 unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } //~ ERROR avoid using named labels
146 // Make sure that non-naked attributes *do* still let the lint happen
148 pub extern "C" fn bar() {
149 unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
150 //~^ ERROR avoid using named labels
154 pub extern "C" fn aaa() {
157 unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
164 pub extern "C" fn bbb() {
167 unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
173 // Make sure that the lint happens within closures
176 asm!("closure1: nop"); //~ ERROR avoid using named labels
180 asm!("closure2: nop"); //~ ERROR avoid using named labels
185 unsafe extern "C" fn _nested() {
186 asm!("ret;", options(noreturn));
190 asm!("closure3: nop"); //~ ERROR avoid using named labels
195 // Don't trigger on global asm
196 global_asm!("aaaaaaaa: nop");