Skip to content

Commit 15d8c00

Browse files
committed
Test RefCell aliasing
1 parent 2b8041f commit 15d8c00

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/test/codegen/noalias-refcell.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// compile-flags: -O -C no-prepopulate-passes -Z mutable-noalias=yes
2+
3+
#![crate_type = "lib"]
4+
5+
use std::cell::{Ref, RefCell, RefMut};
6+
7+
// Make sure that none of the arguments get a `noalias` attribute, because
8+
// the `RefCell` might alias writes after either `Ref`/`RefMut` is dropped.
9+
10+
// CHECK-LABEL: @maybe_aliased(
11+
// CHECK-NOT: noalias
12+
// CHECK-SAME: %_refcell
13+
#[no_mangle]
14+
pub unsafe fn maybe_aliased(_: Ref<'_, i32>, _: RefMut<'_, i32>, _refcell: &RefCell<i32>) {}

src/test/ui/issues/issue-63787.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// run-pass
2+
// compile-flags: -O
3+
4+
// Make sure that `Ref` and `RefMut` do not make false promises about aliasing,
5+
// because once they drop, their reference/pointer can alias other writes.
6+
7+
// Adapted from comex's proof of concept:
8+
// https://github.com/rust-lang/rust/issues/63787#issuecomment-523588164
9+
10+
use std::cell::RefCell;
11+
use std::ops::Deref;
12+
13+
pub fn break_if_r_is_noalias(rc: &RefCell<i32>, r: impl Deref<Target = i32>) -> i32 {
14+
let ptr1 = &*r as *const i32;
15+
let a = *r;
16+
drop(r);
17+
*rc.borrow_mut() = 2;
18+
let r2 = rc.borrow();
19+
let ptr2 = &*r2 as *const i32;
20+
if ptr2 != ptr1 {
21+
panic!();
22+
}
23+
// If LLVM knows the pointers are the same, and if `r` was `noalias`,
24+
// then it may replace this with `a + a`, ignoring the earlier write.
25+
a + *r2
26+
}
27+
28+
fn main() {
29+
let mut rc = RefCell::new(1);
30+
let res = break_if_r_is_noalias(&rc, rc.borrow());
31+
assert_eq!(res, 3);
32+
33+
*rc.get_mut() = 1;
34+
let res = break_if_r_is_noalias(&rc, rc.borrow_mut());
35+
assert_eq!(res, 3);
36+
}

0 commit comments

Comments
 (0)