Auto merge of #3004 - RalfJung:borrow-tests, r=RalfJung

add some SB and TB tests

Also I realized the `direct_mut_to_const_raw` test can be enabled in TB, so let's do that.
This commit is contained in:
bors 2023-08-02 17:10:58 +00:00
commit 0640ae9430
2 changed files with 77 additions and 11 deletions

View File

@ -10,7 +10,7 @@ fn main() {
mut_raw_mut(); mut_raw_mut();
partially_invalidate_mut(); partially_invalidate_mut();
drop_after_sharing(); drop_after_sharing();
direct_mut_to_const_raw(); // direct_mut_to_const_raw();
two_raw(); two_raw();
shr_and_raw(); shr_and_raw();
disjoint_mutable_subborrows(); disjoint_mutable_subborrows();
@ -19,6 +19,7 @@ fn main() {
mut_below_shr(); mut_below_shr();
wide_raw_ptr_in_tuple(); wide_raw_ptr_in_tuple();
not_unpin_not_protected(); not_unpin_not_protected();
write_does_not_invalidate_all_aliases();
} }
// Make sure that reading from an `&mut` does, like reborrowing to `&`, // Make sure that reading from an `&mut` does, like reborrowing to `&`,
@ -110,14 +111,13 @@ fn drop_after_sharing() {
} }
// Make sure that coercing &mut T to *const T produces a writeable pointer. // Make sure that coercing &mut T to *const T produces a writeable pointer.
fn direct_mut_to_const_raw() { // TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604>
// TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604> /*fn direct_mut_to_const_raw() {
/*let x = &mut 0; let x = &mut 0;
let y: *const i32 = x; let y: *const i32 = x;
unsafe { *(y as *mut i32) = 1; } unsafe { *(y as *mut i32) = 1; }
assert_eq!(*x, 1); assert_eq!(*x, 1);
*/ }*/
}
// Make sure that we can create two raw pointers from a mutable reference and use them both. // Make sure that we can create two raw pointers from a mutable reference and use them both.
fn two_raw() { fn two_raw() {
@ -238,3 +238,28 @@ fn not_unpin_not_protected() {
drop(unsafe { Box::from_raw(raw) }); drop(unsafe { Box::from_raw(raw) });
}); });
} }
fn write_does_not_invalidate_all_aliases() {
mod other {
/// Some private memory to store stuff in.
static mut S: *mut i32 = 0 as *mut i32;
pub fn lib1(x: &&mut i32) {
unsafe {
S = (x as *const &mut i32).cast::<*mut i32>().read();
}
}
pub fn lib2() {
unsafe {
*S = 1337;
}
}
}
let x = &mut 0;
other::lib1(&x);
*x = 42; // a write to x -- invalidates other pointers?
other::lib2();
assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
}

View File

@ -10,6 +10,8 @@ fn main() {
aliasing_read_only_mutable_refs(); aliasing_read_only_mutable_refs();
string_as_mut_ptr(); string_as_mut_ptr();
two_mut_protected_same_alloc(); two_mut_protected_same_alloc();
direct_mut_to_const_raw();
local_addr_of_mut();
// Stacked Borrows tests // Stacked Borrows tests
read_does_not_invalidate1(); read_does_not_invalidate1();
@ -19,7 +21,6 @@ fn main() {
mut_raw_mut(); mut_raw_mut();
partially_invalidate_mut(); partially_invalidate_mut();
drop_after_sharing(); drop_after_sharing();
direct_mut_to_const_raw();
two_raw(); two_raw();
shr_and_raw(); shr_and_raw();
disjoint_mutable_subborrows(); disjoint_mutable_subborrows();
@ -28,6 +29,18 @@ fn main() {
mut_below_shr(); mut_below_shr();
wide_raw_ptr_in_tuple(); wide_raw_ptr_in_tuple();
not_unpin_not_protected(); not_unpin_not_protected();
write_does_not_invalidate_all_aliases();
}
#[allow(unused_assignments)]
fn local_addr_of_mut() {
let mut local = 0;
let ptr = ptr::addr_of_mut!(local);
// In SB, `local` and `*ptr` would have different tags, but in TB they have the same tag.
local = 1;
unsafe { *ptr = 2 };
local = 3;
unsafe { *ptr = 4 };
} }
// Tree Borrows has no issue with several mutable references existing // Tree Borrows has no issue with several mutable references existing
@ -172,12 +185,12 @@ fn drop_after_sharing() {
// Make sure that coercing &mut T to *const T produces a writeable pointer. // Make sure that coercing &mut T to *const T produces a writeable pointer.
fn direct_mut_to_const_raw() { fn direct_mut_to_const_raw() {
// TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604> let x = &mut 0;
/*let x = &mut 0;
let y: *const i32 = x; let y: *const i32 = x;
unsafe { *(y as *mut i32) = 1; } unsafe {
*(y as *mut i32) = 1;
}
assert_eq!(*x, 1); assert_eq!(*x, 1);
*/
} }
// Make sure that we can create two raw pointers from a mutable reference and use them both. // Make sure that we can create two raw pointers from a mutable reference and use them both.
@ -298,3 +311,31 @@ fn not_unpin_not_protected() {
drop(unsafe { Box::from_raw(raw) }); drop(unsafe { Box::from_raw(raw) });
}); });
} }
fn write_does_not_invalidate_all_aliases() {
// In TB there are other ways to do that (`addr_of!(*x)` has the same tag as `x`),
// but let's still make sure this SB test keeps working.
mod other {
/// Some private memory to store stuff in.
static mut S: *mut i32 = 0 as *mut i32;
pub fn lib1(x: &&mut i32) {
unsafe {
S = (x as *const &mut i32).cast::<*mut i32>().read();
}
}
pub fn lib2() {
unsafe {
*S = 1337;
}
}
}
let x = &mut 0;
other::lib1(&x);
*x = 42; // a write to x -- invalidates other pointers?
other::lib2();
assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
}