Skip to content

Stacked Borrows: test raw-ref-to-field with raw ptr tracking #1614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows
* [TiKV creating overlapping mutable reference and raw pointer](https://github.com/tikv/tikv/pull/7709)
* [Windows `Env` iterator using a raw pointer outside its valid memory area](https://github.com/rust-lang/rust/pull/70479)
* [`VecDeque::iter_mut` creating overlapping mutable references](https://github.com/rust-lang/rust/issues/74029)
* [Standard library `SipHasher` using a raw pointer outside its valid memory area](https://github.com/rust-lang/rust/pull/78484)
* [Various standard library aliasing issues involving raw pointers](https://github.com/rust-lang/rust/pull/78602)

## License

Expand Down
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a53fb30e3bf2655b0563da6d561c23cda5f3ec11
5cdf5b882da9e8b7c73b5cadeb7745cb68f6ff63
2 changes: 2 additions & 0 deletions tests/run-pass/rc.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// compile-flags: -Zmiri-track-raw-pointers
// ignore-windows (FIXME: tracking raw pointers does not work on Windows)
#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

Expand Down
13 changes: 13 additions & 0 deletions tests/run-pass/stacked-borrows/int-to-ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
fn main() {
ref_raw_int_raw();
}

// Just to make sure that casting a ref to raw, to int and back to raw
// and only then using it works. This rules out ideas like "do escape-to-raw lazily";
// after casting to int and back, we lost the tag that could have let us do that.
fn ref_raw_int_raw() {
let mut x = 3;
let xref = &mut x;
let xraw = xref as *mut i32 as usize as *mut i32;
assert_eq!(unsafe { *xraw }, 3);
}
36 changes: 25 additions & 11 deletions tests/run-pass/stacked-borrows/stacked-borrows.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// compile-flags: -Zmiri-track-raw-pointers
// ignore-windows (FIXME: tracking raw pointers does not work on Windows)
#![feature(raw_ref_macros)]
use std::ptr;

// Test various stacked-borrows-related things.
fn main() {
read_does_not_invalidate1();
read_does_not_invalidate2();
ref_raw_int_raw();
mut_raw_then_mut_shr();
mut_shr_then_mut_raw();
mut_raw_mut();
Expand All @@ -12,6 +16,7 @@ fn main() {
two_raw();
shr_and_raw();
disjoint_mutable_subborrows();
raw_ref_to_part();
}

// Make sure that reading from an `&mut` does, like reborrowing to `&`,
Expand All @@ -37,16 +42,6 @@ fn read_does_not_invalidate2() {
assert_eq!(*foo(&mut (1, 2)), 2);
}

// Just to make sure that casting a ref to raw, to int and back to raw
// and only then using it works. This rules out ideas like "do escape-to-raw lazily";
// after casting to int and back, we lost the tag that could have let us do that.
fn ref_raw_int_raw() {
let mut x = 3;
let xref = &mut x;
let xraw = xref as *mut i32 as usize as *mut i32;
assert_eq!(unsafe { *xraw }, 3);
}

// Escape a mut to raw, then share the same mut and use the share, then the raw.
// That should work.
fn mut_raw_then_mut_shr() {
Expand Down Expand Up @@ -162,3 +157,22 @@ fn disjoint_mutable_subborrows() {
a.push_str(" world");
eprintln!("{:?} {:?}", a, b);
}

fn raw_ref_to_part() {
struct Part {
_lame: i32,
}

#[repr(C)]
struct Whole {
part: Part,
extra: i32,
}

let it = Box::new(Whole { part: Part { _lame: 0 }, extra: 42 });
let whole = ptr::raw_mut!(*Box::leak(it));
let part = unsafe { ptr::raw_mut!((*whole).part) };
let typed = unsafe { &mut *(part as *mut Whole) };
assert!(typed.extra == 42);
drop(unsafe { Box::from_raw(whole) });
}
2 changes: 1 addition & 1 deletion tests/run-pass/thread-local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn main() {
// Initialize the keys we use to check destructor ordering
for (key, global) in KEYS.iter_mut().zip(GLOBALS.iter_mut()) {
*key = create(Some(mem::transmute(dtor as unsafe extern fn(*mut u64))));
set(*key, global as *const _ as *mut _);
set(*key, global as *mut _ as *mut u8);
}

// Initialize cannary
Expand Down