also use compute_size_in_bytes for relevant multiplications in Miri
This commit is contained in:
parent
3b806d337c
commit
268f6cf558
8 changed files with 64 additions and 40 deletions
|
@ -216,7 +216,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
self.copy_intrinsic(&args[0], &args[1], &args[2], /*nonoverlapping*/ false)?;
|
||||
}
|
||||
sym::write_bytes => {
|
||||
self.write_bytes_intrinsic(&args[0], &args[1], &args[2])?;
|
||||
self.write_bytes_intrinsic(&args[0], &args[1], &args[2], "write_bytes")?;
|
||||
}
|
||||
sym::compare_bytes => {
|
||||
let result = self.compare_bytes_intrinsic(&args[0], &args[1], &args[2])?;
|
||||
|
@ -634,11 +634,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn write_bytes_intrinsic(
|
||||
pub fn write_bytes_intrinsic(
|
||||
&mut self,
|
||||
dst: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
|
||||
byte: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
|
||||
count: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
|
||||
name: &'static str,
|
||||
) -> InterpResult<'tcx> {
|
||||
let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap())?;
|
||||
|
||||
|
@ -648,9 +649,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
// `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max),
|
||||
// but no actual allocation can be big enough for the difference to be noticeable.
|
||||
let len = self.compute_size_in_bytes(layout.size, count).ok_or_else(|| {
|
||||
err_ub_custom!(fluent::const_eval_size_overflow, name = "write_bytes")
|
||||
})?;
|
||||
let len = self
|
||||
.compute_size_in_bytes(layout.size, count)
|
||||
.ok_or_else(|| err_ub_custom!(fluent::const_eval_size_overflow, name = name))?;
|
||||
|
||||
let bytes = std::iter::repeat(byte).take(len.bytes_usize());
|
||||
self.write_bytes_ptr(dst, bytes)
|
||||
|
|
|
@ -222,7 +222,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
} else {
|
||||
Allocation::try_uninit(size, align)?
|
||||
};
|
||||
self.allocate_raw_ptr(alloc, kind)
|
||||
self.insert_allocation(alloc, kind)
|
||||
}
|
||||
|
||||
pub fn allocate_bytes_ptr(
|
||||
|
@ -233,14 +233,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
mutability: Mutability,
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
let alloc = Allocation::from_bytes(bytes, align, mutability);
|
||||
self.allocate_raw_ptr(alloc, kind)
|
||||
self.insert_allocation(alloc, kind)
|
||||
}
|
||||
|
||||
pub fn allocate_raw_ptr(
|
||||
pub fn insert_allocation(
|
||||
&mut self,
|
||||
alloc: Allocation<M::Provenance, (), M::Bytes>,
|
||||
kind: MemoryKind<M::MemoryKind>,
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
assert!(alloc.size() <= self.max_size_of_val());
|
||||
let id = self.tcx.reserve_alloc_id();
|
||||
debug_assert_ne!(
|
||||
Some(kind),
|
||||
|
|
|
@ -290,7 +290,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
/// Computes the total size of this access, `count * elem_size`,
|
||||
/// checking for overflow beyond isize::MAX.
|
||||
pub(super) fn compute_size_in_bytes(&self, elem_size: Size, count: u64) -> Option<Size> {
|
||||
pub fn compute_size_in_bytes(&self, elem_size: Size, count: u64) -> Option<Size> {
|
||||
// `checked_mul` applies `u64` limits independent of the target pointer size... but the
|
||||
// subsequent check for `max_size_of_val` means we also handle 32bit targets correctly.
|
||||
// (We cannot use `Size::checked_mul` as that enforces `obj_size_bound` as the limit, which
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue