提交 3637aa86 编写于 作者: R Ralf Jung

allow any offset on integer pointers

上级 8de11101
...@@ -892,19 +892,19 @@ pub(super) fn wrapping_pointer_offset(&self, ptr: PrimVal, pointee_ty: Ty<'tcx>, ...@@ -892,19 +892,19 @@ pub(super) fn wrapping_pointer_offset(&self, ptr: PrimVal, pointee_ty: Ty<'tcx>,
} }
pub(super) fn pointer_offset(&self, ptr: PrimVal, pointee_ty: Ty<'tcx>, offset: i64) -> EvalResult<'tcx, PrimVal> { pub(super) fn pointer_offset(&self, ptr: PrimVal, pointee_ty: Ty<'tcx>, offset: i64) -> EvalResult<'tcx, PrimVal> {
if offset == 0 { if ptr == PrimVal::from_u128(0) { // rule out NULL pointers
// rustc relies on Offset-by-0 to be well-defined even for "bad" pointers like Unique::empty(). return Err(EvalError::InvalidPointerMath);
return Ok(ptr);
} }
// FIXME: assuming here that type size is < i64::max_value() // FIXME: assuming here that type size is < i64::max_value()
let pointee_size = self.type_size(pointee_ty)?.expect("cannot offset a pointer to an unsized type") as i64; let pointee_size = self.type_size(pointee_ty)?.expect("cannot offset a pointer to an unsized type") as i64;
if pointee_size == 0 {
// rustc relies on offsetting pointers to zsts to be a nop
return Ok(ptr);
}
return if let Some(offset) = offset.checked_mul(pointee_size) { return if let Some(offset) = offset.checked_mul(pointee_size) {
let ptr = ptr.signed_offset(offset, self.memory.layout)?; let ptr = ptr.signed_offset(offset, self.memory.layout)?;
self.memory.check_bounds(ptr.to_ptr()?, false)?; // Do not do bounds-checking for integers or ZST; they can never alias a normal pointer anyway.
if let PrimVal::Ptr(ptr) = ptr {
if !ptr.points_to_zst() {
self.memory.check_bounds(ptr, false)?;
}
}
Ok(ptr) Ok(ptr)
} else { } else {
Err(EvalError::OverflowingMath) Err(EvalError::OverflowingMath)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册