diff --git a/src/lib.rs b/src/lib.rs index f61abea62e0b..17b20d003e93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -637,15 +637,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { let alloc = memory.get(ptr.alloc_id)?; - let base_addr = match alloc.extra.base_addr.borrow().clone() { - Some(base_addr) => base_addr, + let mut base_addr = alloc.extra.base_addr.borrow_mut(); + + let addr = match *base_addr { + Some(addr) => addr, None => { - let base_addr = extra.addr; + let addr = extra.addr; extra.addr += alloc.bytes.len() as u64; - *alloc.extra.base_addr.borrow_mut() = Some(base_addr); + *base_addr = Some(addr); - let elem = (base_addr, ptr.alloc_id); + let elem = (addr, ptr.alloc_id); if let Err(pos) = extra.vec.binary_search(&elem) { extra.vec.insert(pos, elem); @@ -653,10 +655,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { return err!(Unreachable); } - base_addr + addr } }; - Ok(base_addr + ptr.offset.bytes()) + Ok(addr + ptr.offset.bytes()) } } diff --git a/src/operator.rs b/src/operator.rs index b05d435ef644..7dd3b3526cdc 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -44,6 +44,16 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> { trace!("ptr_op: {:?} {:?} {:?}", *left, bin_op, *right); + if self.memory().extra.seed.is_some() && bin_op != Offset { + let l_bits = self.force_bits(left.imm.to_scalar()?, left.layout.size)?; + let r_bits = self.force_bits(right.imm.to_scalar()?, right.layout.size)?; + + let left = ImmTy::from_scalar(Scalar::from_uint(l_bits, left.layout.size), left.layout); + let right = ImmTy::from_scalar(Scalar::from_uint(r_bits, left.layout.size), right.layout); + + return self.binary_op(bin_op, left, right); + } + // Operations that support fat pointers match bin_op { Eq | Ne => { diff --git a/tests/run-pass/intptrcast-truncate.rs b/tests/run-pass/intptrcast-truncate.rs new file mode 100644 index 000000000000..7c49af87f886 --- /dev/null +++ b/tests/run-pass/intptrcast-truncate.rs @@ -0,0 +1,8 @@ +// compile-flags: -Zmiri-seed=0000000000000000 + +fn main() { + let x = &42 as *const i32 as usize; + let y = x * 2; + let z = y as u8 as usize; + assert_eq!(z, y % 256); +}