1
Fork 0

interpret: simplify pointer arithmetic logic

This commit is contained in:
Ralf Jung 2024-08-01 10:19:13 +02:00
parent de78cb56b2
commit 5d5c97aad7
27 changed files with 73 additions and 187 deletions

View file

@ -560,17 +560,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.frame().body
}
#[inline(always)]
pub fn sign_extend(&self, value: u128, ty: TyAndLayout<'_>) -> u128 {
assert!(ty.abi.is_signed());
ty.size.sign_extend(value)
}
#[inline(always)]
pub fn truncate(&self, value: u128, ty: TyAndLayout<'_>) -> u128 {
ty.size.truncate(value)
}
#[inline]
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
ty.is_freeze(*self.tcx, self.param_env)

View file

@ -206,7 +206,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
} else {
(val_bits >> shift_bits) | (val_bits << inv_shift_bits)
};
let truncated_bits = self.truncate(result_bits, layout_val);
let truncated_bits = layout_val.size.truncate(result_bits);
let result = Scalar::from_uint(truncated_bits, layout_val.size);
self.write_scalar(result, dest)?;
}
@ -580,13 +580,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ptr: Pointer<Option<M::Provenance>>,
offset_bytes: i64,
) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
// We first compute the pointer with overflow checks, to get a specific error for when it
// overflows (though technically this is redundant with the following inbounds check).
let result = ptr.signed_offset(offset_bytes, self)?;
// The offset must be in bounds starting from `ptr`.
self.check_ptr_access_signed(ptr, offset_bytes, CheckInAllocMsg::PointerArithmeticTest)?;
// Done.
Ok(result)
// This also implies that there is no overflow, so we are done.
Ok(ptr.wrapping_signed_offset(offset_bytes, self))
}
/// Copy `count*size_of::<T>()` many bytes from `*src` to `*dst`.

View file

@ -473,7 +473,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
throw_ub!(PointerOutOfBounds {
alloc_id,
alloc_size,
ptr_offset: self.target_usize_to_isize(offset),
ptr_offset: self.sign_extend_to_target_isize(offset),
inbounds_size: size,
msg,
})

View file

@ -285,10 +285,8 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
// projections are type-checked and bounds-checked.
assert!(offset + layout.size <= self.layout.size);
let new_offset = Size::from_bytes(
ecx.data_layout()
.offset(old_offset.unwrap_or(Size::ZERO).bytes(), offset.bytes())?,
);
// Size `+`, ensures no overflow.
let new_offset = old_offset.unwrap_or(Size::ZERO) + offset;
PlaceTy {
place: Place::Local { local, offset: Some(new_offset), locals_addr },

View file

@ -362,7 +362,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// of the first element.
let elem_size = first.layout.size;
let first_ptr = first.ptr();
let rest_ptr = first_ptr.offset(elem_size, self)?;
let rest_ptr = first_ptr.wrapping_offset(elem_size, self);
// No alignment requirement since `copy_op` above already checked it.
self.mem_copy_repeatedly(
first_ptr,