Skip to content

Commit 69358d0

Browse files
committed
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.
2 parents 26ee292 + 5d071eb commit 69358d0

File tree

2 files changed

+77
-11
lines changed

2 files changed

+77
-11
lines changed

tests/pass/stacked-borrows/stacked-borrows.rs

+31-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() {
1010
mut_raw_mut();
1111
partially_invalidate_mut();
1212
drop_after_sharing();
13-
direct_mut_to_const_raw();
13+
// direct_mut_to_const_raw();
1414
two_raw();
1515
shr_and_raw();
1616
disjoint_mutable_subborrows();
@@ -19,6 +19,7 @@ fn main() {
1919
mut_below_shr();
2020
wide_raw_ptr_in_tuple();
2121
not_unpin_not_protected();
22+
write_does_not_invalidate_all_aliases();
2223
}
2324

2425
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
@@ -110,14 +111,13 @@ fn drop_after_sharing() {
110111
}
111112

112113
// Make sure that coercing &mut T to *const T produces a writeable pointer.
113-
fn direct_mut_to_const_raw() {
114-
// TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604>
115-
/*let x = &mut 0;
114+
// TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604>
115+
/*fn direct_mut_to_const_raw() {
116+
let x = &mut 0;
116117
let y: *const i32 = x;
117118
unsafe { *(y as *mut i32) = 1; }
118119
assert_eq!(*x, 1);
119-
*/
120-
}
120+
}*/
121121

122122
// Make sure that we can create two raw pointers from a mutable reference and use them both.
123123
fn two_raw() {
@@ -238,3 +238,28 @@ fn not_unpin_not_protected() {
238238
drop(unsafe { Box::from_raw(raw) });
239239
});
240240
}
241+
242+
fn write_does_not_invalidate_all_aliases() {
243+
mod other {
244+
/// Some private memory to store stuff in.
245+
static mut S: *mut i32 = 0 as *mut i32;
246+
247+
pub fn lib1(x: &&mut i32) {
248+
unsafe {
249+
S = (x as *const &mut i32).cast::<*mut i32>().read();
250+
}
251+
}
252+
253+
pub fn lib2() {
254+
unsafe {
255+
*S = 1337;
256+
}
257+
}
258+
}
259+
260+
let x = &mut 0;
261+
other::lib1(&x);
262+
*x = 42; // a write to x -- invalidates other pointers?
263+
other::lib2();
264+
assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
265+
}

tests/pass/tree_borrows/tree-borrows.rs

+46-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ fn main() {
1010
aliasing_read_only_mutable_refs();
1111
string_as_mut_ptr();
1212
two_mut_protected_same_alloc();
13+
direct_mut_to_const_raw();
14+
local_addr_of_mut();
1315

1416
// Stacked Borrows tests
1517
read_does_not_invalidate1();
@@ -19,7 +21,6 @@ fn main() {
1921
mut_raw_mut();
2022
partially_invalidate_mut();
2123
drop_after_sharing();
22-
direct_mut_to_const_raw();
2324
two_raw();
2425
shr_and_raw();
2526
disjoint_mutable_subborrows();
@@ -28,6 +29,18 @@ fn main() {
2829
mut_below_shr();
2930
wide_raw_ptr_in_tuple();
3031
not_unpin_not_protected();
32+
write_does_not_invalidate_all_aliases();
33+
}
34+
35+
#[allow(unused_assignments)]
36+
fn local_addr_of_mut() {
37+
let mut local = 0;
38+
let ptr = ptr::addr_of_mut!(local);
39+
// In SB, `local` and `*ptr` would have different tags, but in TB they have the same tag.
40+
local = 1;
41+
unsafe { *ptr = 2 };
42+
local = 3;
43+
unsafe { *ptr = 4 };
3144
}
3245

3346
// Tree Borrows has no issue with several mutable references existing
@@ -172,12 +185,12 @@ fn drop_after_sharing() {
172185

173186
// Make sure that coercing &mut T to *const T produces a writeable pointer.
174187
fn direct_mut_to_const_raw() {
175-
// TODO: This is currently disabled, waiting on a decision on <https://github.com/rust-lang/rust/issues/56604>
176-
/*let x = &mut 0;
188+
let x = &mut 0;
177189
let y: *const i32 = x;
178-
unsafe { *(y as *mut i32) = 1; }
190+
unsafe {
191+
*(y as *mut i32) = 1;
192+
}
179193
assert_eq!(*x, 1);
180-
*/
181194
}
182195

183196
// 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() {
298311
drop(unsafe { Box::from_raw(raw) });
299312
});
300313
}
314+
315+
fn write_does_not_invalidate_all_aliases() {
316+
// In TB there are other ways to do that (`addr_of!(*x)` has the same tag as `x`),
317+
// but let's still make sure this SB test keeps working.
318+
319+
mod other {
320+
/// Some private memory to store stuff in.
321+
static mut S: *mut i32 = 0 as *mut i32;
322+
323+
pub fn lib1(x: &&mut i32) {
324+
unsafe {
325+
S = (x as *const &mut i32).cast::<*mut i32>().read();
326+
}
327+
}
328+
329+
pub fn lib2() {
330+
unsafe {
331+
*S = 1337;
332+
}
333+
}
334+
}
335+
336+
let x = &mut 0;
337+
other::lib1(&x);
338+
*x = 42; // a write to x -- invalidates other pointers?
339+
other::lib2();
340+
assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated
341+
}

0 commit comments

Comments
 (0)