refactor away IntegerPtr

This commit is contained in:
Oliver Schneider 2016-09-22 15:47:16 +02:00
parent 875a4542f9
commit 38748fa615
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
10 changed files with 24 additions and 44 deletions

View file

@ -10,7 +10,7 @@ use syntax::codemap::Span;
pub enum EvalError<'tcx> {
FunctionPointerTyMismatch(&'tcx BareFnTy<'tcx>, &'tcx BareFnTy<'tcx>),
DanglingPointerDeref,
ZstAllocAccess,
InvalidMemoryAccess,
InvalidFunctionPointer,
InvalidBool,
InvalidDiscriminant,
@ -20,7 +20,6 @@ pub enum EvalError<'tcx> {
allocation_size: usize,
},
ReadPointerAsBytes,
ReadBytesAsPointer,
InvalidPointerMath,
ReadUndefBytes,
InvalidBoolOp(mir::BinOp),
@ -54,8 +53,8 @@ impl<'tcx> Error for EvalError<'tcx> {
match *self {
EvalError::FunctionPointerTyMismatch(..) =>
"tried to call a function through a function pointer of a different type",
EvalError::ZstAllocAccess =>
"tried to access the ZST allocation",
EvalError::InvalidMemoryAccess =>
"tried to access memory through an invalid pointer",
EvalError::DanglingPointerDeref =>
"dangling pointer was dereferenced",
EvalError::InvalidFunctionPointer =>
@ -68,8 +67,6 @@ impl<'tcx> Error for EvalError<'tcx> {
"pointer offset outside bounds of allocation",
EvalError::ReadPointerAsBytes =>
"a raw memory access tried to access part of a pointer value as raw bytes",
EvalError::ReadBytesAsPointer =>
"attempted to interpret some raw bytes as a pointer address",
EvalError::InvalidPointerMath =>
"attempted to do math or a comparison on pointers into different allocations",
EvalError::ReadUndefBytes =>

View file

@ -25,8 +25,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
U16(u) => self.cast_const_int(u as u64, ty, false),
U32(u) => self.cast_const_int(u as u64, ty, false),
Char(c) => self.cast_const_int(c as u64, ty, false),
U64(u) |
IntegerPtr(u) => self.cast_const_int(u, ty, false),
U64(u) => self.cast_const_int(u, ty, false),
FnPtr(ptr) |
Ptr(ptr) => self.cast_ptr(ptr, ty),
}
@ -74,7 +73,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
ty::TyFloat(ast::FloatTy::F64) => Ok(F64(v as f64)),
ty::TyFloat(ast::FloatTy::F32) if negative => Ok(F32(v as i64 as f32)),
ty::TyFloat(ast::FloatTy::F32) => Ok(F32(v as f32)),
ty::TyRawPtr(_) => Ok(IntegerPtr(v)),
ty::TyRawPtr(_) => Ok(Ptr(Pointer::from_int(v as usize))),
ty::TyChar if v as u8 as u64 == v => Ok(Char(v as u8 as char)),
ty::TyChar => Err(EvalError::InvalidChar(v)),
_ => Err(EvalError::Unimplemented(format!("int to {:?} cast", ty))),

View file

@ -1064,13 +1064,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
&ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
&ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
if self.type_is_sized(ty) {
match self.memory.read_ptr(ptr) {
Ok(p) => PrimVal::Ptr(p),
Err(EvalError::ReadBytesAsPointer) => {
PrimVal::IntegerPtr(self.memory.read_usize(ptr)?)
}
Err(e) => return Err(e),
}
PrimVal::Ptr(self.memory.read_ptr(ptr)?)
} else {
bug!("primitive read of fat pointer type: {:?}", ty);
}

View file

@ -132,18 +132,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let ptr_arg = args_ptrs[0];
let offset = self.memory.read_isize(args_ptrs[1])?;
match self.memory.read_ptr(ptr_arg) {
Ok(ptr) => {
let result_ptr = ptr.offset(offset as isize * pointee_size);
self.memory.write_ptr(dest, result_ptr)?;
}
Err(EvalError::ReadBytesAsPointer) => {
let addr = self.memory.read_isize(ptr_arg)?;
let result_addr = addr + offset * pointee_size as i64;
self.memory.write_isize(dest, result_addr)?;
}
Err(e) => return Err(e),
}
let ptr = self.memory.read_ptr(ptr_arg)?;
let result_ptr = ptr.offset(offset as isize * pointee_size);
self.memory.write_ptr(dest, result_ptr)?;
}
"overflowing_sub" => {

View file

@ -55,6 +55,12 @@ impl Pointer {
pub fn points_to_zst(&self) -> bool {
self.alloc_id == ZST_ALLOC_ID
}
pub fn from_int(i: usize) -> Self {
Pointer {
alloc_id: ZST_ALLOC_ID,
offset: i,
}
}
fn zst_ptr() -> Self {
Pointer {
alloc_id: ZST_ALLOC_ID,
@ -279,7 +285,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
Some(alloc) => Ok(alloc),
None => match self.functions.get(&id) {
Some(_) => Err(EvalError::DerefFunctionPointer),
None if id == ZST_ALLOC_ID => Err(EvalError::ZstAllocAccess),
None if id == ZST_ALLOC_ID => Err(EvalError::InvalidMemoryAccess),
None => Err(EvalError::DanglingPointerDeref),
}
}
@ -291,7 +297,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
Some(alloc) => Ok(alloc),
None => match self.functions.get(&id) {
Some(_) => Err(EvalError::DerefFunctionPointer),
None if id == ZST_ALLOC_ID => Err(EvalError::ZstAllocAccess),
None if id == ZST_ALLOC_ID => Err(EvalError::InvalidMemoryAccess),
None => Err(EvalError::DanglingPointerDeref),
}
}
@ -511,7 +517,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
let alloc = self.get(ptr.alloc_id)?;
match alloc.relocations.get(&ptr.offset) {
Some(&alloc_id) => Ok(Pointer { alloc_id: alloc_id, offset: offset }),
None => Err(EvalError::ReadBytesAsPointer),
None => Ok(Pointer::from_int(offset)),
}
}
@ -522,7 +528,6 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
}
pub fn write_primval(&mut self, ptr: Pointer, val: PrimVal) -> EvalResult<'tcx, ()> {
let pointer_size = self.pointer_size();
match val {
PrimVal::Bool(b) => self.write_bool(ptr, b),
PrimVal::I8(n) => self.write_int(ptr, n as i64, 1),
@ -534,7 +539,6 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
PrimVal::U32(n) => self.write_uint(ptr, n as u64, 4),
PrimVal::U64(n) => self.write_uint(ptr, n as u64, 8),
PrimVal::Char(c) => self.write_uint(ptr, c as u64, 4),
PrimVal::IntegerPtr(n) => self.write_uint(ptr, n as u64, pointer_size),
PrimVal::F32(f) => self.write_f32(ptr, f),
PrimVal::F64(f) => self.write_f64(ptr, f),
PrimVal::FnPtr(p) |

View file

@ -14,7 +14,6 @@ pub enum PrimVal {
Ptr(Pointer),
FnPtr(Pointer),
IntegerPtr(u64),
Char(char),
F32(f32), F64(f64),
@ -209,14 +208,8 @@ pub fn binary_op<'tcx>(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> Eva
})
}
(IntegerPtr(l), IntegerPtr(r)) => int_binops!(IntegerPtr, l, r),
(Ptr(_), IntegerPtr(_)) |
(IntegerPtr(_), Ptr(_)) |
(FnPtr(_), Ptr(_)) |
(Ptr(_), FnPtr(_)) |
(FnPtr(_), IntegerPtr(_)) |
(IntegerPtr(_), FnPtr(_)) =>
(Ptr(_), FnPtr(_)) =>
unrelated_ptr_ops(bin_op)?,
(FnPtr(l_ptr), FnPtr(r_ptr)) => match bin_op {

View file

@ -1,4 +1,4 @@
fn main() {
let x: i32 = unsafe { *std::ptr::null() }; //~ ERROR: attempted to interpret some raw bytes as a pointer address
let x: i32 = unsafe { *std::ptr::null() }; //~ ERROR: tried to access memory through an invalid pointer
panic!("this should never print: {}", x);
}

View file

@ -1,5 +1,5 @@
fn main() {
let p = 42 as *const i32;
let x = unsafe { *p }; //~ ERROR: attempted to interpret some raw bytes as a pointer address
let x = unsafe { *p }; //~ ERROR: tried to access memory through an invalid pointer
panic!("this should never print: {}", x);
}

View file

@ -1,4 +1,4 @@
fn main() {
let x = &() as *const () as *const i32;
let _ = unsafe { *x }; //~ ERROR: tried to access the ZST allocation
let _ = unsafe { *x }; //~ ERROR: tried to access memory through an invalid pointer
}

View file

@ -21,4 +21,6 @@ fn main() {
assert_eq!(use_zst(), A);
assert_eq!(&A as *const A as *const (), &() as *const _);
assert_eq!(&A as *const A, &A as *const A);
let x = 42 as *mut ();
unsafe { *x = (); }
}