From 6197f4fac93f2d23f3b2b367f2bcc8342c3595fc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 4 Jun 2017 10:42:02 -0700 Subject: [PATCH] Permit int->ptr->int roundtrip --- src/eval_context.rs | 1 + src/memory.rs | 10 ++++++++-- tests/run-pass/ptr_int_casts.rs | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/run-pass/ptr_int_casts.rs diff --git a/src/eval_context.rs b/src/eval_context.rs index 142d90f8dc4d..8eba793c9f65 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -1438,6 +1438,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { panic!("Failed to access local: {:?}", err); } Ok(Value::ByRef(ptr)) => { + write!(msg, " by ref:").unwrap(); allocs.push(ptr.alloc_id); } Ok(Value::ByVal(val)) => { diff --git a/src/memory.rs b/src/memory.rs index bfdc45c921d1..e21b9c9e4d36 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -605,7 +605,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { if size == 0 { return Ok(&[]); } - if self.relocations(ptr, size)?.count() != 0 { + if self.has_non_int_relocations(ptr, size)? { return Err(EvalError::ReadPointerAsBytes); } self.check_defined(ptr, size)?; @@ -703,7 +703,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { let offset = ptr.offset as usize; match alloc.bytes[offset..].iter().position(|&c| c == 0) { Some(size) => { - if self.relocations(ptr, (size + 1) as u64)?.count() != 0 { + if self.has_non_int_relocations(ptr, (size + 1) as u64)? { return Err(EvalError::ReadPointerAsBytes); } self.check_defined(ptr, (size + 1) as u64)?; @@ -887,6 +887,12 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { Ok(self.get(ptr.alloc_id)?.relocations.range(start..end)) } + fn has_non_int_relocations(&self, ptr: Pointer, size: u64) + -> EvalResult<'tcx, bool> + { + Ok(self.relocations(ptr, size)?.any(|(_, &alloc_id)| alloc_id != NEVER_ALLOC_ID)) + } + fn clear_relocations(&mut self, ptr: Pointer, size: u64) -> EvalResult<'tcx> { // Find all relocations overlapping the given range. let keys: Vec<_> = self.relocations(ptr, size)?.map(|(&k, _)| k).collect(); diff --git a/tests/run-pass/ptr_int_casts.rs b/tests/run-pass/ptr_int_casts.rs new file mode 100644 index 000000000000..4983ea4f886b --- /dev/null +++ b/tests/run-pass/ptr_int_casts.rs @@ -0,0 +1,16 @@ +// fn eq_ref(x: &T, y: &T) -> bool { +// x as *const _ == y as *const _ +// } + +fn main() { + // int-ptr-int + assert_eq!(1 as *const i32 as usize, 1); + + // TODO +// { // ptr-int-ptr +// let x = 13; +// let y = &x as *const _ as usize; +// let y = y as *const _; +// assert!(eq_ref(&x, unsafe { &*y })); +// } +}