Add tests for asm goto
This commit is contained in:
parent
31f078ea99
commit
4677a71369
51
tests/codegen/asm-goto.rs
Normal file
51
tests/codegen/asm-goto.rs
Normal file
@ -0,0 +1,51 @@
|
||||
//@ compile-flags: -O
|
||||
//@ only-x86_64
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
#![feature(asm_goto)]
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn panicky() {}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&mut self) {
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @asm_goto
|
||||
#[no_mangle]
|
||||
pub unsafe fn asm_goto() {
|
||||
// CHECK: callbr void asm sideeffect alignstack inteldialect "
|
||||
// CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
|
||||
asm!("jmp {}", label {});
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @asm_goto_with_outputs
|
||||
#[no_mangle]
|
||||
pub unsafe fn asm_goto_with_outputs() -> u64 {
|
||||
let out: u64;
|
||||
// CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect "
|
||||
// CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]]
|
||||
asm!("{} /* {} */", out(reg) out, label { return 1; });
|
||||
// CHECK: [[JUMPBB]]:
|
||||
// CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ]
|
||||
// CHECK-NEXT: ret i64 [[RET]]
|
||||
out
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @asm_goto_noreturn
|
||||
#[no_mangle]
|
||||
pub unsafe fn asm_goto_noreturn() -> u64 {
|
||||
let out: u64;
|
||||
// CHECK: callbr void asm sideeffect alignstack inteldialect "
|
||||
// CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]]
|
||||
asm!("jmp {}", label { return 1; }, options(noreturn));
|
||||
// CHECK: [[JUMPBB]]:
|
||||
// CHECK-NEXT: ret i64 1
|
||||
out
|
||||
}
|
@ -142,3 +142,5 @@ fn main() {
|
||||
//~^ ERROR asm template must be a string literal
|
||||
global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
|
||||
//~^ ERROR asm template must be a string literal
|
||||
global_asm!("{}", label {});
|
||||
//~^ ERROR expected operand, options, or additional template string
|
||||
|
@ -176,17 +176,17 @@ LL | asm!("{a}", a = const foo, a = const bar);
|
||||
|
|
||||
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
|
||||
|
||||
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `""`
|
||||
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `""`
|
||||
--> $DIR/parse-error.rs:82:29
|
||||
|
|
||||
LL | asm!("", options(), "");
|
||||
| ^^ expected one of 9 possible tokens
|
||||
| ^^ expected one of 10 possible tokens
|
||||
|
||||
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
|
||||
error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `label`, `lateout`, `options`, `out`, or `sym`, found `"{}"`
|
||||
--> $DIR/parse-error.rs:84:33
|
||||
|
|
||||
LL | asm!("{}", in(reg) foo, "{}", out(reg) foo);
|
||||
| ^^^^ expected one of 9 possible tokens
|
||||
| ^^^^ expected one of 10 possible tokens
|
||||
|
||||
error: asm template must be a string literal
|
||||
--> $DIR/parse-error.rs:86:14
|
||||
@ -362,6 +362,12 @@ LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
|
||||
|
|
||||
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected operand, options, or additional template string
|
||||
--> $DIR/parse-error.rs:145:19
|
||||
|
|
||||
LL | global_asm!("{}", label {});
|
||||
| ^^^^^^^^ expected operand, options, or additional template string
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/parse-error.rs:39:37
|
||||
|
|
||||
@ -407,6 +413,6 @@ LL | let mut bar = 0;
|
||||
LL | asm!("{a}", a = const foo, a = const bar);
|
||||
| ^^^ non-constant value
|
||||
|
||||
error: aborting due to 63 previous errors
|
||||
error: aborting due to 64 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0435`.
|
||||
|
@ -1,5 +1,7 @@
|
||||
//@ only-x86_64
|
||||
|
||||
#![feature(asm_unwind, asm_goto)]
|
||||
|
||||
use std::arch::{asm, global_asm};
|
||||
|
||||
fn main() {
|
||||
@ -14,6 +16,8 @@ fn main() {
|
||||
//~^ ERROR asm with the `pure` option must have at least one output
|
||||
asm!("{}", out(reg) foo, options(noreturn));
|
||||
//~^ ERROR asm outputs are not allowed with the `noreturn` option
|
||||
asm!("{}", label {}, options(may_unwind));
|
||||
//~^ ERROR asm labels are not allowed with the `may_unwind` option
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -1,35 +1,41 @@
|
||||
error: the `nomem` and `readonly` options are mutually exclusive
|
||||
--> $DIR/bad-options.rs:8:18
|
||||
--> $DIR/bad-options.rs:10:18
|
||||
|
|
||||
LL | asm!("", options(nomem, readonly));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `pure` and `noreturn` options are mutually exclusive
|
||||
--> $DIR/bad-options.rs:10:18
|
||||
--> $DIR/bad-options.rs:12:18
|
||||
|
|
||||
LL | asm!("", options(pure, nomem, noreturn));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: asm with the `pure` option must have at least one output
|
||||
--> $DIR/bad-options.rs:10:18
|
||||
--> $DIR/bad-options.rs:12:18
|
||||
|
|
||||
LL | asm!("", options(pure, nomem, noreturn));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: asm with the `pure` option must have at least one output
|
||||
--> $DIR/bad-options.rs:13:33
|
||||
--> $DIR/bad-options.rs:15:33
|
||||
|
|
||||
LL | asm!("{}", in(reg) foo, options(pure, nomem));
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: asm outputs are not allowed with the `noreturn` option
|
||||
--> $DIR/bad-options.rs:15:20
|
||||
--> $DIR/bad-options.rs:17:20
|
||||
|
|
||||
LL | asm!("{}", out(reg) foo, options(noreturn));
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: asm labels are not allowed with the `may_unwind` option
|
||||
--> $DIR/bad-options.rs:19:20
|
||||
|
|
||||
LL | asm!("{}", label {}, options(may_unwind));
|
||||
| ^^^^^^^^
|
||||
|
||||
error: asm with `clobber_abi` must specify explicit registers for outputs
|
||||
--> $DIR/bad-options.rs:22:20
|
||||
--> $DIR/bad-options.rs:26:20
|
||||
|
|
||||
LL | asm!("{}", out(reg) foo, clobber_abi("C"));
|
||||
| ^^^^^^^^^^^^ ---------------- clobber_abi
|
||||
@ -37,7 +43,7 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"));
|
||||
| generic outputs
|
||||
|
||||
error: asm with `clobber_abi` must specify explicit registers for outputs
|
||||
--> $DIR/bad-options.rs:24:20
|
||||
--> $DIR/bad-options.rs:28:20
|
||||
|
|
||||
LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
|
||||
| ^^^^^^^^^^^^ ---------------- ---------------- clobber_abi
|
||||
@ -46,43 +52,43 @@ LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
|
||||
| generic outputs
|
||||
|
||||
error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
|
||||
--> $DIR/bad-options.rs:31:25
|
||||
--> $DIR/bad-options.rs:35:25
|
||||
|
|
||||
LL | global_asm!("", options(nomem));
|
||||
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||
|
||||
error: expected one of `)`, `att_syntax`, or `raw`, found `readonly`
|
||||
--> $DIR/bad-options.rs:33:25
|
||||
--> $DIR/bad-options.rs:37:25
|
||||
|
|
||||
LL | global_asm!("", options(readonly));
|
||||
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||
|
||||
error: expected one of `)`, `att_syntax`, or `raw`, found `noreturn`
|
||||
--> $DIR/bad-options.rs:35:25
|
||||
--> $DIR/bad-options.rs:39:25
|
||||
|
|
||||
LL | global_asm!("", options(noreturn));
|
||||
| ^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||
|
||||
error: expected one of `)`, `att_syntax`, or `raw`, found `pure`
|
||||
--> $DIR/bad-options.rs:37:25
|
||||
--> $DIR/bad-options.rs:41:25
|
||||
|
|
||||
LL | global_asm!("", options(pure));
|
||||
| ^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||
|
||||
error: expected one of `)`, `att_syntax`, or `raw`, found `nostack`
|
||||
--> $DIR/bad-options.rs:39:25
|
||||
--> $DIR/bad-options.rs:43:25
|
||||
|
|
||||
LL | global_asm!("", options(nostack));
|
||||
| ^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||
|
||||
error: expected one of `)`, `att_syntax`, or `raw`, found `preserves_flags`
|
||||
--> $DIR/bad-options.rs:41:25
|
||||
--> $DIR/bad-options.rs:45:25
|
||||
|
|
||||
LL | global_asm!("", options(preserves_flags));
|
||||
| ^^^^^^^^^^^^^^^ expected one of `)`, `att_syntax`, or `raw`
|
||||
|
||||
error: invalid ABI for `clobber_abi`
|
||||
--> $DIR/bad-options.rs:20:18
|
||||
--> $DIR/bad-options.rs:24:18
|
||||
|
|
||||
LL | asm!("", clobber_abi("foo"));
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
@ -90,12 +96,12 @@ LL | asm!("", clobber_abi("foo"));
|
||||
= note: the following ABIs are supported on this target: `C`, `system`, `efiapi`, `win64`, `sysv64`
|
||||
|
||||
error: `C` ABI specified multiple times
|
||||
--> $DIR/bad-options.rs:24:52
|
||||
--> $DIR/bad-options.rs:28:52
|
||||
|
|
||||
LL | asm!("{}", out(reg) foo, clobber_abi("C"), clobber_abi("C"));
|
||||
| ---------------- ^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| previously specified here
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
23
tests/ui/asm/x86_64/goto.mirunsafeck.stderr
Normal file
23
tests/ui/asm/x86_64/goto.mirunsafeck.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
warning: unreachable statement
|
||||
--> $DIR/goto.rs:99:9
|
||||
|
|
||||
LL | / asm!(
|
||||
LL | | "jmp {}",
|
||||
LL | | label {
|
||||
LL | | return;
|
||||
LL | | },
|
||||
LL | | options(noreturn)
|
||||
LL | | );
|
||||
| |_________- any code following this expression is unreachable
|
||||
LL | unreachable!();
|
||||
| ^^^^^^^^^^^^^^ unreachable statement
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/goto.rs:89:8
|
||||
|
|
||||
LL | #[warn(unreachable_code)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
111
tests/ui/asm/x86_64/goto.rs
Normal file
111
tests/ui/asm/x86_64/goto.rs
Normal file
@ -0,0 +1,111 @@
|
||||
//@ only-x86_64
|
||||
//@ run-pass
|
||||
//@ needs-asm-support
|
||||
//@ revisions: mirunsafeck thirunsafeck
|
||||
//@ [thirunsafeck]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![deny(unreachable_code)]
|
||||
#![feature(asm_goto)]
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
fn goto_fallthough() {
|
||||
unsafe {
|
||||
asm!(
|
||||
"/* {} */",
|
||||
label {
|
||||
unreachable!();
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn goto_jump() {
|
||||
unsafe {
|
||||
let mut value = false;
|
||||
asm!(
|
||||
"jmp {}",
|
||||
label {
|
||||
value = true;
|
||||
}
|
||||
);
|
||||
assert!(value);
|
||||
}
|
||||
}
|
||||
|
||||
// asm goto with outputs cause miscompilation in LLVM. UB can be triggered
|
||||
// when outputs are used inside the label block when optimisation is enabled.
|
||||
// See: https://github.com/llvm/llvm-project/issues/74483
|
||||
/*
|
||||
fn goto_out_fallthrough() {
|
||||
unsafe {
|
||||
let mut out: usize;
|
||||
asm!(
|
||||
"lea {}, [{} + 1]",
|
||||
"/* {} */",
|
||||
out(reg) out,
|
||||
in(reg) 0x12345678usize,
|
||||
label {
|
||||
unreachable!();
|
||||
}
|
||||
);
|
||||
assert_eq!(out, 0x12345679);
|
||||
}
|
||||
}
|
||||
|
||||
fn goto_out_jump() {
|
||||
unsafe {
|
||||
let mut value = false;
|
||||
let mut out: usize;
|
||||
asm!(
|
||||
"lea {}, [{} + 1]",
|
||||
"jmp {}",
|
||||
out(reg) out,
|
||||
in(reg) 0x12345678usize,
|
||||
label {
|
||||
value = true;
|
||||
assert_eq!(out, 0x12345679);
|
||||
}
|
||||
);
|
||||
assert!(value);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
fn goto_noreturn() {
|
||||
unsafe {
|
||||
let a;
|
||||
asm!(
|
||||
"jmp {}",
|
||||
label {
|
||||
a = 1;
|
||||
},
|
||||
options(noreturn)
|
||||
);
|
||||
assert_eq!(a, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[warn(unreachable_code)]
|
||||
fn goto_noreturn_diverge() {
|
||||
unsafe {
|
||||
asm!(
|
||||
"jmp {}",
|
||||
label {
|
||||
return;
|
||||
},
|
||||
options(noreturn)
|
||||
);
|
||||
unreachable!();
|
||||
//~^ WARN unreachable statement
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
goto_fallthough();
|
||||
goto_jump();
|
||||
// goto_out_fallthrough();
|
||||
// goto_out_jump();
|
||||
goto_noreturn();
|
||||
goto_noreturn_diverge();
|
||||
}
|
23
tests/ui/asm/x86_64/goto.thirunsafeck.stderr
Normal file
23
tests/ui/asm/x86_64/goto.thirunsafeck.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
warning: unreachable statement
|
||||
--> $DIR/goto.rs:99:9
|
||||
|
|
||||
LL | / asm!(
|
||||
LL | | "jmp {}",
|
||||
LL | | label {
|
||||
LL | | return;
|
||||
LL | | },
|
||||
LL | | options(noreturn)
|
||||
LL | | );
|
||||
| |_________- any code following this expression is unreachable
|
||||
LL | unreachable!();
|
||||
| ^^^^^^^^^^^^^^ unreachable statement
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/goto.rs:89:8
|
||||
|
|
||||
LL | #[warn(unreachable_code)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
10
tests/ui/feature-gates/feature-gate-asm_goto.rs
Normal file
10
tests/ui/feature-gates/feature-gate-asm_goto.rs
Normal file
@ -0,0 +1,10 @@
|
||||
//@ only-x86_64
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
asm!("jmp {}", label {});
|
||||
//~^ ERROR label operands for inline assembly are unstable
|
||||
}
|
||||
}
|
13
tests/ui/feature-gates/feature-gate-asm_goto.stderr
Normal file
13
tests/ui/feature-gates/feature-gate-asm_goto.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error[E0658]: label operands for inline assembly are unstable
|
||||
--> $DIR/feature-gate-asm_goto.rs:7:24
|
||||
|
|
||||
LL | asm!("jmp {}", label {});
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: see issue #119364 <https://github.com/rust-lang/rust/issues/119364> for more information
|
||||
= help: add `#![feature(asm_goto)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue
Block a user