add return-place-protection tail-call test, and fix previous test
This commit is contained in:
parent
f6edc8a07c
commit
7d066c4edd
10 changed files with 157 additions and 39 deletions
|
|
@ -1,5 +1,5 @@
|
|||
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.read() };
|
||||
| ^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
|
@ -7,9 +7,9 @@ LL | unsafe { ptr.read() };
|
|||
= 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
|
||||
= note: BACKTRACE:
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.read() };
|
||||
| ^^^^^^^^^^ not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||
|
|
@ -7,7 +7,7 @@ LL | unsafe { ptr.read() };
|
|||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | / mir! {
|
||||
LL | | {
|
||||
|
|
@ -18,14 +18,14 @@ LL | | }
|
|||
LL | | }
|
||||
| |_____^
|
||||
help: <TAG> is this argument
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.read() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: Undefined Behavior: read access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.read() };
|
||||
| ^^^^^^^^^^ read access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||
|
|
@ -9,7 +9,7 @@ LL | unsafe { ptr.read() };
|
|||
= help: this foreign read access would cause the protected tag <TAG> (currently Active) to become Disabled
|
||||
= help: protected tags must never be Disabled
|
||||
help: the accessed tag <TAG> was created here
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | / mir! {
|
||||
LL | | {
|
||||
|
|
@ -20,20 +20,20 @@ LL | | }
|
|||
LL | | }
|
||||
| |_____^
|
||||
help: the protected tag <TAG> was created here, in the initial state Reserved
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.read() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
help: the protected tag <TAG> later transitioned to Active due to a child write access at offsets [0x0..0x4]
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.read() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_read.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// This does need an aliasing model.
|
||||
// This does need an aliasing model and protectors.
|
||||
//@revisions: stack tree
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
#![feature(raw_ref_op)]
|
||||
|
|
@ -14,8 +14,8 @@ pub fn main() {
|
|||
let _x = 0;
|
||||
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), ReturnTo(after_call), UnwindContinue())
|
||||
// its return place. Writing to that pointer is UB.
|
||||
Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
|
|
@ -27,7 +27,7 @@ pub fn main() {
|
|||
fn myfun(ptr: *mut i32) -> i32 {
|
||||
// This overwrites the return place, which shouldn't be possible through another pointer.
|
||||
unsafe { ptr.write(0) };
|
||||
//~[stack]^ ERROR: tag does not exist in the borrow stack
|
||||
//~[stack]^ ERROR: strongly protected
|
||||
//~[tree]| ERROR: /write access .* forbidden/
|
||||
13
|
||||
}
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^
|
||||
| |
|
||||
| attempting a write access using <TAG> at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
|
||||
| this error occurs as part of an access at ALLOC[0x0..0x4]
|
||||
| ^^^^^^^^^^^^ not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | / mir! {
|
||||
LL | | {
|
||||
|
|
@ -20,18 +17,18 @@ LL | | let ptr = &raw mut _x;
|
|||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
help: <TAG> was later invalidated at offsets [0x0..0x4] by a Unique in-place function argument/return passing protection
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
help: <TAG> is this argument
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(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
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error: Undefined Behavior: write access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^ write access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||
|
|
@ -9,7 +9,7 @@ LL | unsafe { ptr.write(0) };
|
|||
= help: this foreign write access would cause the protected tag <TAG> (currently Active) to become Disabled
|
||||
= help: protected tags must never be Disabled
|
||||
help: the accessed tag <TAG> was created here
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | / mir! {
|
||||
LL | | {
|
||||
|
|
@ -20,23 +20,23 @@ LL | | }
|
|||
LL | | }
|
||||
| |_____^
|
||||
help: the protected tag <TAG> was created here, in the initial state Reserved
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: the protected tag <TAG> later transitioned to Active due to a child write access at offsets [0x0..0x4]
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
= note: inside `myfun` at $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing2.rs:LL:CC
|
||||
--> $DIR/return_pointer_aliasing_write.rs:LL:CC
|
||||
|
|
||||
LL | Call(_x = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(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
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// This does need an aliasing model and protectors.
|
||||
//@revisions: stack tree
|
||||
//@[tree]compile-flags: -Zmiri-tree-borrows
|
||||
#![feature(raw_ref_op)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(custom_mir)]
|
||||
#![feature(explicit_tail_calls)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::intrinsics::mir::*;
|
||||
|
||||
#[custom_mir(dialect = "runtime", phase = "optimized")]
|
||||
pub fn main() {
|
||||
mir! {
|
||||
{
|
||||
let _x = 0;
|
||||
let ptr = &raw mut _x;
|
||||
// We arrange for `myfun` to have a pointer that aliases
|
||||
// its return place. Writing to that pointer is UB.
|
||||
Call(*ptr = myfun(ptr), ReturnTo(after_call), UnwindContinue())
|
||||
}
|
||||
|
||||
after_call = {
|
||||
Return()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn myfun(ptr: *mut i32) -> i32 {
|
||||
become myfun2(ptr)
|
||||
}
|
||||
|
||||
fn myfun2(ptr: *mut i32) -> i32 {
|
||||
// This overwrites the return place, which shouldn't be possible through another pointer.
|
||||
unsafe { ptr.write(0) };
|
||||
//~[stack]^ ERROR: strongly protected
|
||||
//~[tree]| ERROR: /write access .* forbidden/
|
||||
13
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^ not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||
help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | / mir! {
|
||||
LL | | {
|
||||
LL | | let _x = 0;
|
||||
LL | | let ptr = &raw mut _x;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
help: <TAG> is this argument
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `myfun2` at $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(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
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
error: Undefined Behavior: write access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^ write access through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
|
||||
|
|
||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
|
||||
= help: the accessed tag <TAG> (root of the allocation) is foreign to the protected tag <TAG> (i.e., it is not a child)
|
||||
= help: this foreign write access would cause the protected tag <TAG> (currently Active) to become Disabled
|
||||
= help: protected tags must never be Disabled
|
||||
help: the accessed tag <TAG> was created here
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | / mir! {
|
||||
LL | | {
|
||||
LL | | let _x = 0;
|
||||
LL | | let ptr = &raw mut _x;
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^
|
||||
help: the protected tag <TAG> was created here, in the initial state Reserved
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: the protected tag <TAG> later transitioned to Active due to a child write access at offsets [0x0..0x4]
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { ptr.write(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `myfun2` at $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/return_pointer_aliasing_write_tail_call.rs:LL:CC
|
||||
|
|
||||
LL | Call(*ptr = myfun(ptr), ReturnTo(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
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue