Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/dummy_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ impl HasStaticRootDefId for DummyMachine {

impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
interpret::compile_time_machine!(<'tcx>);
const PANIC_ON_ALLOC_FAIL: bool = true;
const ALLOC_FAILURE_REPORTING: interpret::AllocFailureReporting =
interpret::AllocFailureReporting::Suppress;

// We want to just eval random consts in the program, so `eval_mir_const` can fail.
const ALL_CONSTS_ARE_PRECHECKED: bool = false;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,8 @@ impl<'tcx> CompileTimeMachine<'tcx> {
impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
compile_time_machine!(<'tcx>);

const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
const ALLOC_FAILURE_REPORTING: interpret::AllocFailureReporting =
interpret::AllocFailureReporting::Emit;

#[inline(always)]
fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool {
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ pub trait MayLeak: Copy {
fn may_leak(self) -> bool;
}

pub enum AllocFailureReporting {
Emit,
Suppress,
}

/// The functionality needed by memory to manage its allocations
pub trait AllocMap<K: Hash + Eq, V> {
/// Tests if the map contains the given key.
Expand Down Expand Up @@ -139,8 +144,8 @@ pub trait Machine<'tcx>: Sized {
/// that is added to the memory so that the work is not done twice.
const GLOBAL_KIND: Option<Self::MemoryKind>;

/// Should the machine panic on allocation failures?
const PANIC_ON_ALLOC_FAIL: bool;
/// How should allocation failures be surfaced?
const ALLOC_FAILURE_REPORTING: AllocFailureReporting = AllocFailureReporting::Emit;

/// Determines whether `eval_mir_constant` can never fail because all required consts have
/// already been checked before.
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ use rustc_middle::{bug, throw_ub_format};
use tracing::{debug, instrument, trace};

use super::{
AllocBytes, AllocId, AllocInit, AllocMap, AllocRange, Allocation, CheckAlignMsg,
CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine,
MayLeak, Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, alloc_range, err_ub,
err_ub_custom, interp_ok, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
AllocBytes, AllocFailureReporting, AllocId, AllocInit, AllocMap, AllocRange, Allocation,
CheckAlignMsg, CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, MPlaceTy,
Machine, MayLeak, Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, alloc_range,
err_ub, err_ub_custom, interp_ok, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format,
};
use crate::const_eval::ConstEvalErrKind;

Expand Down Expand Up @@ -258,10 +258,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
init: AllocInit,
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
let params = self.machine.get_default_alloc_params();
let alloc = if M::PANIC_ON_ALLOC_FAIL {
Allocation::new(size, align, init, params)
} else {
Allocation::try_new(size, align, init, params)?
let alloc = match M::ALLOC_FAILURE_REPORTING {
AllocFailureReporting::Emit => Allocation::try_new(size, align, init, params)?,
AllocFailureReporting::Suppress => {
Allocation::try_new_silent(size, align, init, params)?
}
};
self.insert_allocation(alloc, kind)
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_const_eval/src/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub use self::intern::{
HasStaticRootDefId, InternError, InternKind, intern_const_alloc_for_constprop,
intern_const_alloc_recursive,
};
pub use self::machine::{AllocMap, Machine, MayLeak, ReturnAction, compile_time_machine};
pub use self::machine::{
AllocFailureReporting, AllocMap, Machine, MayLeak, ReturnAction, compile_time_machine,
};
pub use self::memory::{AllocInfo, AllocKind, AllocRef, AllocRefMut, FnVal, Memory, MemoryKind};
use self::operand::Operand;
pub use self::operand::{ImmTy, Immediate, OpTy};
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,20 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
.into()
}

/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
/// available to the compiler to do so, without emitting a bug.
pub fn try_new_silent<'tcx>(
size: Size,
align: Align,
init: AllocInit,
params: <Bytes as AllocBytes>::AllocParams,
) -> InterpResult<'tcx, Self> {
Self::new_inner(size, align, init, params, || {
InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
})
.into()
}

/// Try to create an Allocation of `size` bytes, panics if there is not enough memory
/// available to the compiler to do so.
///
Expand Down
3 changes: 2 additions & 1 deletion src/tools/miri/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {

const GLOBAL_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Global);

const PANIC_ON_ALLOC_FAIL: bool = false;
const ALLOC_FAILURE_REPORTING: interpret::AllocFailureReporting =
interpret::AllocFailureReporting::Emit;

#[inline(always)]
fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool {
Expand Down
24 changes: 24 additions & 0 deletions tests/ui/mir/gvn-memory-exhausted-no-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//@ compile-flags: -Zmir-opt-level=5
//@ check-pass
//@ only-64bit

#![feature(maybe_uninit_as_bytes)]

use std::mem::MaybeUninit;
use std::ptr::from_ref;

const N: usize = 0x0000_7ff0_0000_0000;

#[inline(never)]
pub fn g(n: &u8) {
let mut xs = MaybeUninit::<[u8; N]>::uninit();
let base = from_ref(&xs.as_bytes()[0]).addr();
let index = from_ref(n).addr() - base;
xs.as_bytes_mut()[index].write(42);
}

pub fn main() {
let n = Box::new(27);
g(&n);
std::process::exit(*n as i32);
}
Loading