The following library:
use std::cell::*;
pub fn break_it(rc: &RefCell<i32>, r: Ref<'_, i32>) {
// `r` has a shared reference, it is passed in as argument and hence
// a barrier is added that marks this memory as read-only for the entire
// duration of this function.
drop(r);
// *oops* here we can mutate that memory.
*rc.borrow_mut() = 2;
}
generates IR for break_it that starts like
; playground::break_it
; Function Attrs: noinline nonlazybind uwtable
define void @_ZN10playground8break_it17hb8a9beeb2affda19E(
{ i64, i32 }* align 8 dereferenceable(16) %rc,
i32* noalias nocapture readonly align 4 dereferenceable(4) %r.0,
i64* nocapture align 8 dereferenceable(8) %r.1)
unnamed_addr #1 personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* @rust_eh_personality {
Note the noalias. That is incorrect, this function violates the noalias assumptions by mutating the data r points to through a pointer (rc) not derived from c. Here's a caller causing bad aliasing:
pub fn main() {
let rc = RefCell::new(0);
break_it(&rc, rc.borrow())
}
RefMut has the same problem when -Zmutable-noalias is set.
Cc @rkruppe @comex
The following library:
generates IR for
break_itthat starts likeNote the
noalias. That is incorrect, this function violates the noalias assumptions by mutating the datarpoints to through a pointer (rc) not derived fromc. Here's a caller causing bad aliasing:RefMuthas the same problem when-Zmutable-noaliasis set.Cc @rkruppe @comex