Skip to content

Commit

Permalink
add some sanity checks in write_immediate_no_validate
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Jul 25, 2023
1 parent 4ea2bd1 commit d127600
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
31 changes: 28 additions & 3 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ where
src: Immediate<M::Provenance>,
dest: &PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx> {
assert!(dest.layout.is_sized(), "Cannot write unsized data");
assert!(dest.layout.is_sized(), "Cannot write unsized immediate data");
trace!("write_immediate: {:?} <- {:?}: {}", *dest, src, dest.layout.ty);

// See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`,
Expand All @@ -591,9 +591,34 @@ where
*self.force_allocation(dest)?
} else {
match M::access_local_mut(self, frame, local)? {
Operand::Immediate(local) => {
Operand::Immediate(local_val) => {
// Local can be updated in-place.
*local = src;
*local_val = src;
// Double-check that the value we are storing and the local fit to each other.
// (*After* doing the update for borrow checker reasons.)
if cfg!(debug_assertions) {
let local_layout =
self.layout_of_local(&self.stack()[frame], local, None)?;
match (src, local_layout.abi) {
(Immediate::Scalar(scalar), Abi::Scalar(s)) => {
assert_eq!(scalar.size(), s.size(self))
}
(
Immediate::ScalarPair(a_val, b_val),
Abi::ScalarPair(a, b),
) => {
assert_eq!(a_val.size(), a.size(self));
assert_eq!(b_val.size(), b.size(self));
}
(Immediate::Uninit, _) => {}
(src, abi) => {
bug!(
"value {src:?} cannot be written into local with type {} (ABI {abi:?})",
local_layout.ty
)
}
};
}
return Ok(());
}
Operand::Indirect(mplace) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
assert!(self.mutability == Mutability::Mut);

// `to_bits_or_ptr_internal` is the right method because we just want to store this data
// as-is into memory.
// as-is into memory. This also double-checks that `val.size()` matches `range.size`.
let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? {
Right(ptr) => {
let (provenance, offset) = ptr.into_parts();
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,14 @@ impl<Prov> Scalar<Prov> {
}
})
}

#[inline]
pub fn size(self) -> Size {
match self {
Scalar::Int(int) => int.size(),
Scalar::Ptr(_ptr, sz) => Size::from_bytes(sz),
}
}
}

impl<'tcx, Prov: Provenance> Scalar<Prov> {
Expand Down

0 comments on commit d127600

Please sign in to comment.