Auto merge of #1614 - RalfJung:raw-retag, r=RalfJung
Stacked Borrows: test raw-ref-to-field with raw ptr tracking Adds a test for https://github.com/rust-lang/rust/pull/78597 (blocked on that landing first)
This commit is contained in:
commit
2590bc64fe
@ -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)
|
* [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)
|
* [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)
|
* [`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
|
## License
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
a53fb30e3bf2655b0563da6d561c23cda5f3ec11
|
5cdf5b882da9e8b7c73b5cadeb7745cb68f6ff63
|
||||||
|
@ -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(new_uninit)]
|
||||||
#![feature(get_mut_unchecked)]
|
#![feature(get_mut_unchecked)]
|
||||||
|
|
||||||
|
13
tests/run-pass/stacked-borrows/int-to-ptr.rs
Normal file
13
tests/run-pass/stacked-borrows/int-to-ptr.rs
Normal file
@ -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);
|
||||||
|
}
|
@ -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.
|
// Test various stacked-borrows-related things.
|
||||||
fn main() {
|
fn main() {
|
||||||
read_does_not_invalidate1();
|
read_does_not_invalidate1();
|
||||||
read_does_not_invalidate2();
|
read_does_not_invalidate2();
|
||||||
ref_raw_int_raw();
|
|
||||||
mut_raw_then_mut_shr();
|
mut_raw_then_mut_shr();
|
||||||
mut_shr_then_mut_raw();
|
mut_shr_then_mut_raw();
|
||||||
mut_raw_mut();
|
mut_raw_mut();
|
||||||
@ -12,6 +16,7 @@ fn main() {
|
|||||||
two_raw();
|
two_raw();
|
||||||
shr_and_raw();
|
shr_and_raw();
|
||||||
disjoint_mutable_subborrows();
|
disjoint_mutable_subborrows();
|
||||||
|
raw_ref_to_part();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
|
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
|
||||||
@ -37,16 +42,6 @@ fn foo(x: &mut (i32, i32)) -> &i32 {
|
|||||||
assert_eq!(*foo(&mut (1, 2)), 2);
|
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.
|
// Escape a mut to raw, then share the same mut and use the share, then the raw.
|
||||||
// That should work.
|
// That should work.
|
||||||
fn mut_raw_then_mut_shr() {
|
fn mut_raw_then_mut_shr() {
|
||||||
@ -162,3 +157,22 @@ unsafe fn borrow_field_b<'a>(this:*mut Foo) -> &'a mut Vec<u32> {
|
|||||||
a.push_str(" world");
|
a.push_str(" world");
|
||||||
eprintln!("{:?} {:?}", a, b);
|
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) });
|
||||||
|
}
|
||||||
|
@ -58,7 +58,7 @@ fn main() {
|
|||||||
// Initialize the keys we use to check destructor ordering
|
// Initialize the keys we use to check destructor ordering
|
||||||
for (key, global) in KEYS.iter_mut().zip(GLOBALS.iter_mut()) {
|
for (key, global) in KEYS.iter_mut().zip(GLOBALS.iter_mut()) {
|
||||||
*key = create(Some(mem::transmute(dtor as unsafe extern fn(*mut u64))));
|
*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
|
// Initialize cannary
|
||||||
|
Loading…
Reference in New Issue
Block a user