mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Auto merge of #61781 - christianpoveda:intptrcast-model, r=oli-obk,RalfJung
prepare for Intptrcast model https://github.com/rust-lang/rust/pull/61668 done right (I hope so). r? @RalfJung @oli-obk
This commit is contained in:
commit
b25ee64497
@ -765,4 +765,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
|
|||||||
pub fn truncate(&self, value: u128, ty: TyLayout<'_>) -> u128 {
|
pub fn truncate(&self, value: u128, ty: TyLayout<'_>) -> u128 {
|
||||||
truncate(value, ty.size)
|
truncate(value, ty.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn force_ptr(
|
||||||
|
&self,
|
||||||
|
scalar: Scalar<M::PointerTag>,
|
||||||
|
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
|
||||||
|
self.memory.force_ptr(scalar)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn force_bits(
|
||||||
|
&self,
|
||||||
|
scalar: Scalar<M::PointerTag>,
|
||||||
|
size: Size
|
||||||
|
) -> InterpResult<'tcx, u128> {
|
||||||
|
self.memory.force_bits(scalar, size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ use rustc::ty::{self, query::TyCtxtAt};
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Allocation, AllocId, InterpResult, Scalar, AllocationExtra,
|
Allocation, AllocId, InterpResult, Scalar, AllocationExtra,
|
||||||
InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind,
|
InterpretCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer,
|
||||||
|
InterpErrorInfo, InterpError
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Whether this kind of memory is allowed to leak
|
/// Whether this kind of memory is allowed to leak
|
||||||
@ -208,4 +209,22 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||||||
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
|
||||||
extra: Self::FrameExtra,
|
extra: Self::FrameExtra,
|
||||||
) -> InterpResult<'tcx>;
|
) -> InterpResult<'tcx>;
|
||||||
|
|
||||||
|
fn int_to_ptr(
|
||||||
|
int: u64,
|
||||||
|
_extra: &Self::MemoryExtra,
|
||||||
|
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
|
||||||
|
if int == 0 {
|
||||||
|
Err(InterpErrorInfo::from(InterpError::InvalidNullPointerUsage))
|
||||||
|
} else {
|
||||||
|
Err(InterpErrorInfo::from(InterpError::ReadBytesAsPointer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ptr_to_int(
|
||||||
|
_ptr: Pointer<Self::PointerTag>,
|
||||||
|
_extra: &Self::MemoryExtra,
|
||||||
|
) -> InterpResult<'tcx, u64> {
|
||||||
|
Err(InterpErrorInfo::from(InterpError::ReadPointerAsBytes))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -627,7 +627,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||||||
if size.bytes() == 0 {
|
if size.bytes() == 0 {
|
||||||
Ok(&[])
|
Ok(&[])
|
||||||
} else {
|
} else {
|
||||||
let ptr = ptr.to_ptr()?;
|
let ptr = self.force_ptr(ptr)?;
|
||||||
self.get(ptr.alloc_id)?.get_bytes(self, ptr, size)
|
self.get(ptr.alloc_id)?.get_bytes(self, ptr, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,8 +714,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||||||
// non-NULLness which already happened.
|
// non-NULLness which already happened.
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let src = src.to_ptr()?;
|
let src = self.force_ptr(src)?;
|
||||||
let dest = dest.to_ptr()?;
|
let dest = self.force_ptr(dest)?;
|
||||||
|
|
||||||
// first copy the relocations to a temporary buffer, because
|
// first copy the relocations to a temporary buffer, because
|
||||||
// `get_bytes_mut` will clear the relocations, which is correct,
|
// `get_bytes_mut` will clear the relocations, which is correct,
|
||||||
@ -874,4 +874,25 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn force_ptr(
|
||||||
|
&self,
|
||||||
|
scalar: Scalar<M::PointerTag>,
|
||||||
|
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
|
||||||
|
match scalar {
|
||||||
|
Scalar::Ptr(ptr) => Ok(ptr),
|
||||||
|
_ => M::int_to_ptr(scalar.to_usize(self)?, &self.extra)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn force_bits(
|
||||||
|
&self,
|
||||||
|
scalar: Scalar<M::PointerTag>,
|
||||||
|
size: Size
|
||||||
|
) -> InterpResult<'tcx, u128> {
|
||||||
|
match scalar.to_bits_or_ptr(size, self) {
|
||||||
|
Ok(bits) => Ok(bits),
|
||||||
|
Err(ptr) => Ok(M::ptr_to_int(ptr, &self.extra)? as u128)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for integer pointers before alignment to report better errors
|
// check for integer pointers before alignment to report better errors
|
||||||
let ptr = ptr.to_ptr()?;
|
let ptr = self.force_ptr(ptr)?;
|
||||||
self.memory.check_align(ptr.into(), ptr_align)?;
|
self.memory.check_align(ptr.into(), ptr_align)?;
|
||||||
match mplace.layout.abi {
|
match mplace.layout.abi {
|
||||||
layout::Abi::Scalar(..) => {
|
layout::Abi::Scalar(..) => {
|
||||||
|
@ -347,7 +347,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
assert!(layout.ty.is_integral());
|
assert!(layout.ty.is_integral());
|
||||||
let val = val.to_bits(layout.size)?;
|
let val = self.force_bits(val, layout.size)?;
|
||||||
let res = match un_op {
|
let res = match un_op {
|
||||||
Not => !val,
|
Not => !val,
|
||||||
Neg => {
|
Neg => {
|
||||||
|
@ -473,7 +473,7 @@ where
|
|||||||
let layout = self.layout_of(self.tcx.types.usize)?;
|
let layout = self.layout_of(self.tcx.types.usize)?;
|
||||||
let n = self.access_local(self.frame(), local, Some(layout))?;
|
let n = self.access_local(self.frame(), local, Some(layout))?;
|
||||||
let n = self.read_scalar(n)?;
|
let n = self.read_scalar(n)?;
|
||||||
let n = n.to_bits(self.tcx.data_layout.pointer_size)?;
|
let n = self.force_bits(n.not_undef()?, self.tcx.data_layout.pointer_size)?;
|
||||||
self.mplace_field(base, u64::try_from(n).unwrap())?
|
self.mplace_field(base, u64::try_from(n).unwrap())?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -753,7 +753,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check for integer pointers before alignment to report better errors
|
// check for integer pointers before alignment to report better errors
|
||||||
let ptr = ptr.to_ptr()?;
|
let ptr = self.force_ptr(ptr)?;
|
||||||
self.memory.check_align(ptr.into(), ptr_align)?;
|
self.memory.check_align(ptr.into(), ptr_align)?;
|
||||||
let tcx = &*self.tcx;
|
let tcx = &*self.tcx;
|
||||||
// FIXME: We should check that there are dest.layout.size many bytes available in
|
// FIXME: We should check that there are dest.layout.size many bytes available in
|
||||||
|
@ -79,7 +79,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
|
|||||||
let (fn_def, abi) = match func.layout.ty.sty {
|
let (fn_def, abi) = match func.layout.ty.sty {
|
||||||
ty::FnPtr(sig) => {
|
ty::FnPtr(sig) => {
|
||||||
let caller_abi = sig.abi();
|
let caller_abi = sig.abi();
|
||||||
let fn_ptr = self.read_scalar(func)?.to_ptr()?;
|
let fn_ptr = self.force_ptr(self.read_scalar(func)?.not_undef()?)?;
|
||||||
let instance = self.memory.get_fn(fn_ptr)?;
|
let instance = self.memory.get_fn(fn_ptr)?;
|
||||||
(instance, caller_abi)
|
(instance, caller_abi)
|
||||||
}
|
}
|
||||||
|
@ -559,7 +559,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||||||
// This is the size in bytes of the whole array.
|
// This is the size in bytes of the whole array.
|
||||||
let size = ty_size * len;
|
let size = ty_size * len;
|
||||||
|
|
||||||
let ptr = mplace.ptr.to_ptr()?;
|
let ptr = self.ecx.force_ptr(mplace.ptr)?;
|
||||||
|
|
||||||
// NOTE: Keep this in sync with the handling of integer and float
|
// NOTE: Keep this in sync with the handling of integer and float
|
||||||
// types above, in `visit_primitive`.
|
// types above, in `visit_primitive`.
|
||||||
|
Loading…
Reference in New Issue
Block a user