]> git.lizzy.rs Git - rust.git/blob - src/test/ui/codegen/issue-63787.rs
Rollup merge of #98356 - lucasthormann:patch-1, r=Mark-Simulacrum
[rust.git] / src / test / ui / codegen / issue-63787.rs
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 }