also consider boxes like unique references
This commit is contained in:
parent
36b97cd76c
commit
b7dbb5e2a7
2 changed files with 37 additions and 8 deletions
|
|
@ -661,14 +661,14 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
|
|||
// Primitives of reference type, that is the one thing we are interested in.
|
||||
fn visit_primitive(&mut self, place: MPlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>
|
||||
{
|
||||
match place.layout.ty.sty {
|
||||
ty::Ref(_, _, mutbl) => {
|
||||
let val = self.ecx.read_immediate(place.into())?;
|
||||
let val = self.ecx.retag_reference(val, mutbl)?;
|
||||
self.ecx.write_immediate(val, place.into())?;
|
||||
}
|
||||
_ => {}, // nothing to do
|
||||
}
|
||||
let mutbl = match place.layout.ty.sty {
|
||||
ty::Ref(_, _, mutbl) => mutbl,
|
||||
ty::Adt(..) if place.layout.ty.is_box() => MutMutable,
|
||||
_ => return Ok(()), // nothing to do
|
||||
};
|
||||
let val = self.ecx.read_immediate(place.into())?;
|
||||
let val = self.ecx.retag_reference(val, mutbl)?;
|
||||
self.ecx.write_immediate(val, place.into())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
fn demo_mut_advanced_unique(mut our: Box<i32>) -> i32 {
|
||||
unknown_code_1(&*our);
|
||||
|
||||
// This "re-asserts" uniqueness of the reference: After writing, we know
|
||||
// our tag is at the top of the stack.
|
||||
*our = 5;
|
||||
|
||||
unknown_code_2();
|
||||
|
||||
// We know this will return 5
|
||||
*our //~ ERROR does not exist on the stack
|
||||
}
|
||||
|
||||
// Now comes the evil context
|
||||
use std::ptr;
|
||||
|
||||
static mut LEAK: *mut i32 = ptr::null_mut();
|
||||
|
||||
fn unknown_code_1(x: &i32) { unsafe {
|
||||
LEAK = x as *const _ as *mut _;
|
||||
} }
|
||||
|
||||
fn unknown_code_2() { unsafe {
|
||||
*LEAK = 7;
|
||||
} }
|
||||
|
||||
fn main() {
|
||||
assert_eq!(demo_mut_advanced_unique(Box::new(0)), 5);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue