]> git.lizzy.rs Git - rust.git/blob - src/test/ui/asm/named-asm-labels.rs
Rollup merge of #99787 - aDotInTheVoid:rdj-dyn, r=camelid,notriddle,GuillaumeGomez
[rust.git] / src / test / ui / asm / named-asm-labels.rs
1 // needs-asm-support
2 // ignore-nvptx64
3 // ignore-spirv
4 // ignore-wasm32
5
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.
13
14 #![feature(naked_functions, asm_const)]
15
16 use std::arch::{asm, global_asm};
17
18 #[no_mangle]
19 pub static FOO: usize = 42;
20
21 fn main() {
22     unsafe {
23         // Basic usage
24         asm!("bar: nop"); //~ ERROR avoid using named labels
25
26         // No following asm
27         asm!("abcd:"); //~ ERROR avoid using named labels
28
29         // Multiple labels on one line
30         asm!("foo: bar1: nop");
31         //~^ ERROR avoid using named labels
32
33         // Multiple lines
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
41
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
47
48         // Escaped newline
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
55
56         // Raw strings
57         asm!(
58             r"
59             blah2: nop
60             blah3: nop
61             "
62         );
63         //~^^^^ ERROR avoid using named labels
64
65         asm!(
66             r###"
67             nop
68             nop ; blah4: nop
69             "###
70         );
71         //~^^^ ERROR avoid using named labels
72
73         // Non-labels
74         // should not trigger lint, but may be invalid asm
75         asm!("ab cd: nop");
76
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");
80
81         // Only `blah1:` should trigger
82         asm!("blah1: 2bar: nop"); //~ ERROR avoid using named labels
83
84         // Duplicate 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
88
89         // Trying to break parsing
90         asm!(":");
91         asm!("\n:\n");
92         asm!("::::");
93
94         // 0x3A is a ':'
95         asm!("fooo\u{003A} nop"); //~ ERROR avoid using named labels
96         asm!("foooo\x3A nop"); //~ ERROR avoid using named labels
97
98         // 0x0A is a newline
99         asm!("fooooo:\u{000A} nop"); //~ ERROR avoid using named labels
100         asm!("foooooo:\x0A nop"); //~ ERROR avoid using named labels
101
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
105
106         // Non-label colons - should pass
107         asm!("mov rax, qword ptr fs:[0]");
108
109         // Comments
110         asm!(
111             r"
112             ab: nop // ab: does foo
113             // cd: nop
114             "
115         );
116         //~^^^^ ERROR avoid using named labels
117
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?
121         asm!(":bbb nop");
122
123         // Test include_str in asm
124         asm!(include_str!("named-asm-labels.s")); //~ ERROR avoid using named labels
125
126         // Test allowing or warning on the lint instead
127         #[allow(named_asm_labels)]
128         {
129             asm!("allowed: nop"); // Should not emit anything
130         }
131
132         #[warn(named_asm_labels)]
133         {
134             asm!("warned: nop"); //~ WARNING avoid using named labels
135         }
136     }
137 }
138
139 // Trigger on naked fns too, even though they can't be inlined, reusing a
140 // label or LTO can cause labels to break
141 #[naked]
142 pub extern "C" fn foo() -> i32 {
143     unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } //~ ERROR avoid using named labels
144 }
145
146 // Make sure that non-naked attributes *do* still let the lint happen
147 #[no_mangle]
148 pub extern "C" fn bar() {
149     unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
150     //~^ ERROR avoid using named labels
151 }
152
153 #[naked]
154 pub extern "C" fn aaa() {
155     fn _local() {}
156
157     unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
158 }
159
160 pub fn normal() {
161     fn _local1() {}
162
163     #[naked]
164     pub extern "C" fn bbb() {
165         fn _very_local() {}
166
167         unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
168     }
169
170     fn _local2() {}
171 }
172
173 // Make sure that the lint happens within closures
174 fn closures() {
175     || unsafe {
176         asm!("closure1: nop"); //~ ERROR avoid using named labels
177     };
178
179     move || unsafe {
180         asm!("closure2: nop"); //~ ERROR avoid using named labels
181     };
182
183     || {
184         #[naked]
185         unsafe extern "C" fn _nested() {
186             asm!("ret;", options(noreturn));
187         }
188
189         unsafe {
190             asm!("closure3: nop"); //~ ERROR avoid using named labels
191         }
192     };
193 }
194
195 // Don't trigger on global asm
196 global_asm!("aaaaaaaa: nop");