Skip to content

Commit 7cfb8a3

Browse files
committed
Add tests for asm goto
1 parent 6836330 commit 7cfb8a3

File tree

7 files changed

+201
-24
lines changed

7 files changed

+201
-24
lines changed

Diff for: tests/codegen/asm-goto.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// compile-flags: -O
2+
// only-x86_64
3+
4+
#![crate_type = "rlib"]
5+
#![feature(asm_goto)]
6+
7+
use std::arch::asm;
8+
9+
#[no_mangle]
10+
pub extern "C" fn panicky() {}
11+
12+
struct Foo;
13+
14+
impl Drop for Foo {
15+
fn drop(&mut self) {
16+
println!();
17+
}
18+
}
19+
20+
// CHECK-LABEL: @asm_goto
21+
#[no_mangle]
22+
pub unsafe fn asm_goto() {
23+
// CHECK: callbr void asm sideeffect alignstack inteldialect "
24+
// CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
25+
asm!("jmp {}", label {});
26+
}
27+
28+
// CHECK-LABEL: @asm_goto_with_outputs
29+
#[no_mangle]
30+
pub unsafe fn asm_goto_with_outputs() -> u64 {
31+
let out: u64;
32+
// CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect "
33+
// CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
34+
asm!("{} /* {} */", out(reg) out, label { return 1; });
35+
// CHECK: [[JUMPBB]]:
36+
// CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ]
37+
// CHECK-NEXT: ret i64 [[RET]]
38+
out
39+
}
40+
41+
// CHECK-LABEL: @asm_goto_noreturn
42+
#[no_mangle]
43+
pub unsafe fn asm_goto_noreturn() -> u64 {
44+
let out: u64;
45+
// CHECK: callbr void asm sideeffect alignstack inteldialect "
46+
// CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]]
47+
asm!("jmp {}", label { return 1; }, options(noreturn));
48+
// CHECK: [[JUMPBB]]:
49+
// CHECK-NEXT: ret i64 1
50+
out
51+
}

Diff for: tests/ui/asm/parse-error.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,17 @@ LL | asm!("{a}", a = const foo, a = const bar);
176176
|
177177
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
178178

179-
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
179+
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""`
180180
--> $DIR/parse-error.rs:82:29
181181
|
182182
LL | asm!("", options(), "");
183-
| ^^ expected one of 9 possible tokens
183+
| ^^ expected one of 10 possible tokens
184184

185-
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
185+
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
186186
--> $DIR/parse-error.rs:84:33
187187
|
188188
LL | asm!("{}", in(reg) foo, "{}", out(reg) foo);
189-
| ^^^^ expected one of 9 possible tokens
189+
| ^^^^ expected one of 10 possible tokens
190190

191191
error: asm template must be a string literal
192192
--> $DIR/parse-error.rs:86:14
@@ -334,17 +334,17 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
334334
|
335335
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
336336

337-
error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
337+
error: expected one of `clobber_abi`, `const`, `label`, `options`, or `sym`, found `""`
338338
--> $DIR/parse-error.rs:137:28
339339
|
340340
LL | global_asm!("", options(), "");
341-
| ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
341+
| ^^ expected one of `clobber_abi`, `const`, `label`, `options`, or `sym`
342342

343-
error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
343+
error: expected one of `clobber_abi`, `const`, `label`, `options`, or `sym`, found `"{}"`
344344
--> $DIR/parse-error.rs:139:30
345345
|
346346
LL | global_asm!("{}", const FOO, "{}", const FOO);
347-
| ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
347+
| ^^^^ expected one of `clobber_abi`, `const`, `label`, `options`, or `sym`
348348

349349
error: asm template must be a string literal
350350
--> $DIR/parse-error.rs:141:13

Diff for: tests/ui/asm/x86_64/bad-options.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// only-x86_64
22

3+
#![feature(asm_unwind, asm_goto)]
4+
35
use std::arch::{asm, global_asm};
46

57
fn main() {
@@ -14,6 +16,8 @@ fn main() {
1416
//~^ ERROR asm with the `pure` option must have at least one output
1517
asm!("{}", out(reg) foo, options(noreturn));
1618
//~^ ERROR asm outputs are not allowed with the `noreturn` option
19+
asm!("{}", label {}, options(may_unwind));
20+
//~^ ERROR asm labels are not allowed with the `may_unwind` option
1721
}
1822

1923
unsafe {

Diff for: tests/ui/asm/x86_64/bad-options.stderr

+22-16
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,49 @@
11
error: the `nomem` and `readonly` options are mutually exclusive
2-
--> $DIR/bad-options.rs:8:18
2+
--> $DIR/bad-options.rs:10:18
33
|
44
LL | asm!("", options(nomem, readonly));
55
| ^^^^^^^^^^^^^^^^^^^^^^^^
66

77
error: the `pure` and `noreturn` options are mutually exclusive
8-
--> $DIR/bad-options.rs:10:18
8+
--> $DIR/bad-options.rs:12:18
99
|
1010
LL | asm!("", options(pure, nomem, noreturn));
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: asm with the `pure` option must have at least one output
14-
--> $DIR/bad-options.rs:10:18
14+
--> $DIR/bad-options.rs:12:18
1515
|
1616
LL | asm!("", options(pure, nomem, noreturn));
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error: asm with the `pure` option must have at least one output
20-
--> $DIR/bad-options.rs:13:33
20+
--> $DIR/bad-options.rs:15:33
2121
|
2222
LL | asm!("{}", in(reg) foo, options(pure, nomem));
2323
| ^^^^^^^^^^^^^^^^^^^^
2424

2525
error: asm outputs are not allowed with the `noreturn` option
26-
--> $DIR/bad-options.rs:15:20
26+
--> $DIR/bad-options.rs:17:20
2727
|
2828
LL | asm!("{}", out(reg) foo, options(noreturn));
2929
| ^^^^^^^^^^^^
3030

31+
error: asm labels are not allowed with the `may_unwind` option
32+
--> $DIR/bad-options.rs:19:20
33+
|
34+
LL | asm!("{}", label {}, options(may_unwind));
35+
| ^^^^^^^^
36+
3137
error: asm with `clobber_abi` must specify explicit registers for outputs
32-
--> $DIR/bad-options.rs:22:20
38+
--> $DIR/bad-options.rs:26:20
3339
|
3440
LL | asm!("{}", out(reg) foo, clobber_abi("C"));
3541
| ^^^^^^^^^^^^ ---------------- clobber_abi
3642
| |
3743
| generic outputs
3844

3945
error: asm with `clobber_abi` must specify explicit registers for outputs
40-
--> $DIR/bad-options.rs:24:20
46+
--> $DIR/bad-options.rs:28:20
4147
|
4248
LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
4349
| ^^^^^^^^^^^^ ---------------- ---------------- clobber_abi
@@ -46,56 +52,56 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
4652
| generic outputs
4753

4854
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
49-
--> $DIR/bad-options.rs:31:25
55+
--> $DIR/bad-options.rs:35:25
5056
|
5157
LL | global_asm!("", options(nomem));
5258
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
5359

5460
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
55-
--> $DIR/bad-options.rs:33:25
61+
--> $DIR/bad-options.rs:37:25
5662
|
5763
LL | global_asm!("", options(readonly));
5864
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
5965

6066
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
61-
--> $DIR/bad-options.rs:35:25
67+
--> $DIR/bad-options.rs:39:25
6268
|
6369
LL | global_asm!("", options(noreturn));
6470
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
6571

6672
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
67-
--> $DIR/bad-options.rs:37:25
73+
--> $DIR/bad-options.rs:41:25
6874
|
6975
LL | global_asm!("", options(pure));
7076
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
7177

7278
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
73-
--> $DIR/bad-options.rs:39:25
79+
--> $DIR/bad-options.rs:43:25
7480
|
7581
LL | global_asm!("", options(nostack));
7682
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
7783

7884
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
79-
--> $DIR/bad-options.rs:41:25
85+
--> $DIR/bad-options.rs:45:25
8086
|
8187
LL | global_asm!("", options(preserves_flags));
8288
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
8389

8490
error: invalid ABI for `clobber_abi`
85-
--> $DIR/bad-options.rs:20:18
91+
--> $DIR/bad-options.rs:24:18
8692
|
8793
LL | asm!("", clobber_abi("foo"));
8894
| ^^^^^^^^^^^^^^^^^^
8995
|
9096
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
9197

9298
error: `C` ABI specified multiple times
93-
--> $DIR/bad-options.rs:24:52
99+
--> $DIR/bad-options.rs:28:52
94100
|
95101
LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
96102
| ---------------- ^^^^^^^^^^^^^^^^
97103
| |
98104
| previously specified here
99105

100-
error: aborting due to 15 previous errors
106+
error: aborting due to 16 previous errors
101107

Diff for: tests/ui/asm/x86_64/goto.rs

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// only-x86_64
2+
// run-pass
3+
// needs-asm-support
4+
// revisions: mirunsafeck thirunsafeck
5+
// [thirunsafeck]compile-flags: -Z thir-unsafeck
6+
7+
#![deny(unreachable_code)]
8+
#![feature(asm_goto)]
9+
10+
use std::arch::asm;
11+
12+
fn goto_fallthough() {
13+
unsafe {
14+
asm!(
15+
"/* {} */",
16+
label {
17+
unreachable!();
18+
}
19+
)
20+
}
21+
}
22+
23+
fn goto_jump() {
24+
unsafe {
25+
let mut value = false;
26+
asm!(
27+
"jmp {}",
28+
label {
29+
value = true;
30+
}
31+
);
32+
assert!(value);
33+
}
34+
}
35+
36+
// asm goto with outputs cause miscompilation in LLVM. UB can be triggered
37+
// when outputs are used inside the label block when optimisation is enabled.
38+
// See: https://github.com/llvm/llvm-project/issues/74483
39+
/*
40+
fn goto_out_fallthrough() {
41+
unsafe {
42+
let mut out: usize;
43+
asm!(
44+
"lea {}, [{} + 1]",
45+
"/* {} */",
46+
out(reg) out,
47+
in(reg) 0x12345678usize,
48+
label {
49+
unreachable!();
50+
}
51+
);
52+
assert_eq!(out, 0x12345679);
53+
}
54+
}
55+
56+
fn goto_out_jump() {
57+
unsafe {
58+
let mut value = false;
59+
let mut out: usize;
60+
asm!(
61+
"lea {}, [{} + 1]",
62+
"jmp {}",
63+
out(reg) out,
64+
in(reg) 0x12345678usize,
65+
label {
66+
value = true;
67+
assert_eq!(out, 0x12345679);
68+
}
69+
);
70+
assert!(value);
71+
}
72+
}
73+
*/
74+
75+
fn goto_noreturn() {
76+
unsafe {
77+
'a: {
78+
asm!(
79+
"jmp {}",
80+
label {
81+
break 'a;
82+
},
83+
options(noreturn)
84+
);
85+
}
86+
}
87+
}
88+
89+
fn main() {
90+
goto_fallthough();
91+
goto_jump();
92+
// goto_out_fallthrough();
93+
// goto_out_jump();
94+
goto_noreturn();
95+
}

Diff for: tests/ui/feature-gates/feature-gate-asm_goto.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// only-x86_64
2+
3+
use std::arch::asm;
4+
5+
fn main() {
6+
unsafe {
7+
asm!("jmp {}", label {});
8+
//~^ ERROR label operands for inline assembly are unstable
9+
}
10+
}

Diff for: tests/ui/feature-gates/feature-gate-asm_goto.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0658]: label operands for inline assembly are unstable
2+
--> $DIR/feature-gate-asm_goto.rs:7:24
3+
|
4+
LL | asm!("jmp {}", label {});
5+
| ^^^^^^^^
6+
|
7+
= help: add `#![feature(asm_goto)]` to the crate attributes to enable
8+
9+
error: aborting due to 1 previous error
10+
11+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)