Skip to content

Commit

Permalink
forcing instead of normalization
Browse files Browse the repository at this point in the history
Normalziation does not work well for dyamically sized types
  • Loading branch information
RalfJung committed Jul 6, 2019
1 parent 9b71a8f commit ac4f6ab
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/librustc_mir/interpret/operand.rs
Expand Up @@ -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
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/librustc_mir/interpret/place.rs
Expand Up @@ -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)
}

Expand Down
15 changes: 11 additions & 4 deletions src/librustc_mir/interpret/validity.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -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)
}
}

0 comments on commit ac4f6ab

Please sign in to comment.