forcing instead of normalization
Normalziation does not work well for dyamically sized types
This commit is contained in:
parent
9b71a8f8ba
commit
ac4f6ab2a0
3 changed files with 17 additions and 12 deletions
|
|
@ -217,13 +217,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
/// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST.
|
||||
/// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
|
||||
#[inline]
|
||||
pub fn normalize_op_ptr(
|
||||
pub fn force_op_ptr(
|
||||
&self,
|
||||
op: OpTy<'tcx, M::PointerTag>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||
match op.try_as_mplace() {
|
||||
Ok(mplace) => Ok(self.normalize_mplace_ptr(mplace)?.into()),
|
||||
Err(imm) => Ok(imm.into()), // Nothing to normalize
|
||||
Ok(mplace) => Ok(self.force_mplace_ptr(mplace)?.into()),
|
||||
Err(imm) => Ok(imm.into()), // Nothing to cast/force
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -327,15 +327,13 @@ where
|
|||
self.memory.check_ptr_access(place.ptr, size, place.align)
|
||||
}
|
||||
|
||||
/// Normalice `place.ptr` to a `Pointer` if this is not a ZST.
|
||||
/// Force `place.ptr` to a `Pointer`.
|
||||
/// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
|
||||
pub fn normalize_mplace_ptr(
|
||||
pub fn force_mplace_ptr(
|
||||
&self,
|
||||
mut place: MPlaceTy<'tcx, M::PointerTag>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
if !place.layout.is_zst() {
|
||||
place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into();
|
||||
}
|
||||
place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into();
|
||||
Ok(place)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -444,7 +444,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
// `!` is a ZST and we want to validate it.
|
||||
// Normalize before handing `place` to tracking because that will
|
||||
// check for duplicates.
|
||||
let place = self.ecx.normalize_mplace_ptr(place)?;
|
||||
let place = if size.bytes() > 0 {
|
||||
self.ecx.force_mplace_ptr(place)
|
||||
.expect("we already bounds-checked")
|
||||
} else {
|
||||
place
|
||||
};
|
||||
let path = &self.path;
|
||||
ref_tracking.track(place, || {
|
||||
// We need to clone the path anyway, make sure it gets created
|
||||
|
|
@ -578,8 +583,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
let ty_size = self.ecx.layout_of(tys)?.size;
|
||||
// This is the size in bytes of the whole array.
|
||||
let size = ty_size * len;
|
||||
// Size is not 0, get a pointer (no cast because we normalized in validate_operand).
|
||||
let ptr = mplace.ptr.assert_ptr();
|
||||
// Size is not 0, get a pointer.
|
||||
let ptr = self.ecx.force_ptr(mplace.ptr)?;
|
||||
|
||||
// NOTE: Keep this in sync with the handling of integer and float
|
||||
// types above, in `visit_primitive`.
|
||||
|
|
@ -654,8 +659,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
ecx: self,
|
||||
};
|
||||
|
||||
// Try to cast to ptr *once* instead of all the time.
|
||||
let op = self.force_op_ptr(op).unwrap_or(op);
|
||||
|
||||
// Run it
|
||||
let op = self.normalize_op_ptr(op)?; // avoid doing ptr-to-int all the time
|
||||
visitor.visit_value(op)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue