Rollup merge of #107756 - RalfJung:miri-out-of-addresses, r=oli-obk
miri: fix ICE when running out of address space Fixes https://github.com/rust-lang/miri/issues/2769 r? `@oli-obk` I didn't add a test since that requires https://github.com/oli-obk/ui_test/issues/38 (host must be 64bit and target 32bit). Also the test takes ~30s, so I am not sure if we want to have it in the test suite?
This commit is contained in:
commit
d044c1bde4
9 changed files with 54 additions and 33 deletions
|
@ -78,13 +78,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
col: u32,
|
||||
) -> MPlaceTy<'tcx, M::Provenance> {
|
||||
let loc_details = &self.tcx.sess.opts.unstable_opts.location_detail;
|
||||
// This can fail if rustc runs out of memory right here. Trying to emit an error would be
|
||||
// pointless, since that would require allocating more memory than these short strings.
|
||||
let file = if loc_details.file {
|
||||
self.allocate_str(filename.as_str(), MemoryKind::CallerLocation, Mutability::Not)
|
||||
.unwrap()
|
||||
} else {
|
||||
// FIXME: This creates a new allocation each time. It might be preferable to
|
||||
// perform this allocation only once, and re-use the `MPlaceTy`.
|
||||
// See https://github.com/rust-lang/rust/pull/89920#discussion_r730012398
|
||||
self.allocate_str("<redacted>", MemoryKind::CallerLocation, Mutability::Not)
|
||||
self.allocate_str("<redacted>", MemoryKind::CallerLocation, Mutability::Not).unwrap()
|
||||
};
|
||||
let line = if loc_details.line { Scalar::from_u32(line) } else { Scalar::from_u32(0) };
|
||||
let col = if loc_details.column { Scalar::from_u32(col) } else { Scalar::from_u32(0) };
|
||||
|
@ -95,8 +98,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
.bound_type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None))
|
||||
.subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter()));
|
||||
let loc_layout = self.layout_of(loc_ty).unwrap();
|
||||
// This can fail if rustc runs out of memory right here. Trying to emit an error would be
|
||||
// pointless, since that would require allocating more memory than a Location.
|
||||
let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap();
|
||||
|
||||
// Initialize fields.
|
||||
|
|
|
@ -291,7 +291,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
fn adjust_alloc_base_pointer(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
) -> Pointer<Self::Provenance>;
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// "Int-to-pointer cast"
|
||||
fn ptr_from_addr_cast(
|
||||
|
@ -505,8 +505,8 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
fn adjust_alloc_base_pointer(
|
||||
_ecx: &InterpCx<$mir, $tcx, Self>,
|
||||
ptr: Pointer<AllocId>,
|
||||
) -> Pointer<AllocId> {
|
||||
ptr
|
||||
) -> InterpResult<$tcx, Pointer<AllocId>> {
|
||||
Ok(ptr)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -171,7 +171,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
_ => {}
|
||||
}
|
||||
// And we need to get the provenance.
|
||||
Ok(M::adjust_alloc_base_pointer(self, ptr))
|
||||
M::adjust_alloc_base_pointer(self, ptr)
|
||||
}
|
||||
|
||||
pub fn create_fn_alloc_ptr(
|
||||
|
@ -200,8 +200,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
kind: MemoryKind<M::MemoryKind>,
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?;
|
||||
// We can `unwrap` since `alloc` contains no pointers.
|
||||
Ok(self.allocate_raw_ptr(alloc, kind).unwrap())
|
||||
self.allocate_raw_ptr(alloc, kind)
|
||||
}
|
||||
|
||||
pub fn allocate_bytes_ptr(
|
||||
|
@ -210,10 +209,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
align: Align,
|
||||
kind: MemoryKind<M::MemoryKind>,
|
||||
mutability: Mutability,
|
||||
) -> Pointer<M::Provenance> {
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
let alloc = Allocation::from_bytes(bytes, align, mutability);
|
||||
// We can `unwrap` since `alloc` contains no pointers.
|
||||
self.allocate_raw_ptr(alloc, kind).unwrap()
|
||||
self.allocate_raw_ptr(alloc, kind)
|
||||
}
|
||||
|
||||
/// This can fail only of `alloc` contains provenance.
|
||||
|
@ -230,7 +228,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
);
|
||||
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
|
||||
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
|
||||
Ok(M::adjust_alloc_base_pointer(self, Pointer::from(id)))
|
||||
M::adjust_alloc_base_pointer(self, Pointer::from(id))
|
||||
}
|
||||
|
||||
pub fn reallocate_ptr(
|
||||
|
|
|
@ -754,8 +754,8 @@ where
|
|||
str: &str,
|
||||
kind: MemoryKind<M::MemoryKind>,
|
||||
mutbl: Mutability,
|
||||
) -> MPlaceTy<'tcx, M::Provenance> {
|
||||
let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl);
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
|
||||
let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?;
|
||||
let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self);
|
||||
let mplace = MemPlace { ptr: ptr.into(), meta: MemPlaceMeta::Meta(meta) };
|
||||
|
||||
|
@ -764,7 +764,7 @@ where
|
|||
ty::TypeAndMut { ty: self.tcx.types.str_, mutbl },
|
||||
);
|
||||
let layout = self.layout_of(ty).unwrap();
|
||||
MPlaceTy { mplace, layout, align: layout.align.abi }
|
||||
Ok(MPlaceTy { mplace, layout, align: layout.align.abi })
|
||||
}
|
||||
|
||||
/// Writes the aggregate to the destination.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue