Custom MIR: Support cleanup blocks
Cleanup blocks are declared with `bb (cleanup) = { ... }`.
`Call` and `Drop` terminators take an additional argument describing the
unwind action, which is one of the following:
* `UnwindContinue()`
* `UnwindUnreachable()`
* `UnwindTerminate(reason)`, where reason is `ReasonAbi` or `ReasonInCleanup`
* `UnwindCleanup(block)`
Also support unwind resume and unwind terminate terminators:
* `UnwindResume()`
* `UnwindTerminate(reason)`
This commit is contained in:
parent
287ae4db75
commit
78da577650
38 changed files with 428 additions and 107 deletions
|
|
@ -14,7 +14,7 @@ fn main() {
|
|||
let ptr = std::ptr::addr_of_mut!(non_copy);
|
||||
// Inside `callee`, the first argument and `*ptr` are basically
|
||||
// aliasing places!
|
||||
Call(_unit = callee(Move(*ptr), ptr), after_call)
|
||||
Call(_unit = callee(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
}
|
||||
after_call = {
|
||||
Return()
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ LL | unsafe { ptr.write(S(0)) };
|
|||
note: inside `main`
|
||||
--> $DIR/arg_inplace_mutate.rs:LL:CC
|
||||
|
|
||||
LL | Call(_unit = callee(Move(*ptr), ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_unit = callee(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ LL | unsafe { ptr.write(S(0)) };
|
|||
note: inside `main`
|
||||
--> $DIR/arg_inplace_mutate.rs:LL:CC
|
||||
|
|
||||
LL | Call(_unit = callee(Move(*ptr), ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_unit = callee(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ fn main() {
|
|||
{
|
||||
let non_copy = S(42);
|
||||
// This could change `non_copy` in-place
|
||||
Call(_unit = change_arg(Move(non_copy)), after_call)
|
||||
Call(_unit = change_arg(Move(non_copy)), after_call, UnwindContinue())
|
||||
}
|
||||
after_call = {
|
||||
// So now we must not be allowed to observe non-copy again.
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ LL | unsafe { ptr.read() };
|
|||
note: inside `main`
|
||||
--> $DIR/arg_inplace_observe_during.rs:LL:CC
|
||||
|
|
||||
LL | Call(_unit = change_arg(Move(*ptr), ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_unit = change_arg(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ fn main() {
|
|||
let non_copy = S(42);
|
||||
let ptr = std::ptr::addr_of_mut!(non_copy);
|
||||
// This could change `non_copy` in-place
|
||||
Call(_unit = change_arg(Move(*ptr), ptr), after_call)
|
||||
Call(_unit = change_arg(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
}
|
||||
after_call = {
|
||||
Return()
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ LL | x.0 = 0;
|
|||
note: inside `main`
|
||||
--> $DIR/arg_inplace_observe_during.rs:LL:CC
|
||||
|
|
||||
LL | Call(_unit = change_arg(Move(*ptr), ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_unit = change_arg(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ LL | x.0 = 0;
|
|||
note: inside `main`
|
||||
--> $DIR/arg_inplace_observe_during.rs:LL:CC
|
||||
|
|
||||
LL | Call(_unit = change_arg(Move(*ptr), ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_unit = change_arg(Move(*ptr), ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ LL | unsafe { ptr.read() };
|
|||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(*ptr = myfun(ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub fn main() {
|
|||
let ptr = &raw mut x;
|
||||
// We arrange for `myfun` to have a pointer that aliases
|
||||
// its return place. Even just reading from that pointer is UB.
|
||||
Call(*ptr = myfun(ptr), after_call)
|
||||
Call(*ptr = myfun(ptr), after_call, UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ LL | unsafe { ptr.read() };
|
|||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(*ptr = myfun(ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ LL | unsafe { ptr.read() };
|
|||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(*ptr = myfun(ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub fn main() {
|
|||
let ptr = &raw mut _x;
|
||||
// We arrange for `myfun` to have a pointer that aliases
|
||||
// its return place. Even just reading from that pointer is UB.
|
||||
Call(_x = myfun(ptr), after_call)
|
||||
Call(_x = myfun(ptr), after_call, UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ LL | unsafe { ptr.write(0) };
|
|||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
|
|
||||
LL | Call(_x = myfun(ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_x = myfun(ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ LL | unsafe { ptr.write(0) };
|
|||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
|
|
||||
LL | Call(_x = myfun(ptr), after_call)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(_x = myfun(ptr), after_call, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ struct S(i32, [u8; 128]);
|
|||
fn docall(out: &mut S) {
|
||||
mir! {
|
||||
{
|
||||
Call(*out = callee(), after_call)
|
||||
Call(*out = callee(), after_call, UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
|
|
@ -37,7 +37,7 @@ fn callee() -> S {
|
|||
// become visible to the outside. In codegen we can see them
|
||||
// but Miri should detect this as UB!
|
||||
RET.0 = 42;
|
||||
Call(_unit = startpanic(), after_call)
|
||||
Call(_unit = startpanic(), after_call, UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ fn call(f: fn(NonZeroU32)) {
|
|||
let tmp = ptr::addr_of!(c);
|
||||
let ptr = tmp as *const NonZeroU32;
|
||||
// The call site now is a NonZeroU32-to-u32 transmute.
|
||||
Call(_res = f(*ptr), retblock) //~ERROR: expected something greater or equal to 1
|
||||
Call(_res = f(*ptr), retblock, UnwindContinue()) //~ERROR: expected something greater or equal to 1
|
||||
}
|
||||
retblock = {
|
||||
Return()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: constructing invalid value: encountered 0, but expected something greater or equal to 1
|
||||
--> $DIR/cast_fn_ptr_invalid_caller_arg.rs:LL:CC
|
||||
|
|
||||
LL | Call(_res = f(*ptr), retblock)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
|
||||
LL | Call(_res = f(*ptr), retblock, UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub fn main() {
|
|||
{
|
||||
let x = 0;
|
||||
let ptr = &raw mut x;
|
||||
Call(*ptr = myfun(), after_call)
|
||||
Call(*ptr = myfun(), after_call, UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue