mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
a277c901d9
This also remove safety information from MIR.
110 lines
2.0 KiB
Rust
110 lines
2.0 KiB
Rust
//@ only-x86_64
|
|
//@ run-pass
|
|
//@ needs-asm-support
|
|
|
|
#![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();
|
|
}
|