adding a err macro for each of the InterpError variants
This commit is contained in:
parent
9782b373b3
commit
8e9d0faff2
18 changed files with 140 additions and 124 deletions
|
|
@ -4,7 +4,6 @@ use super::{
|
|||
Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar,
|
||||
};
|
||||
|
||||
use super::error::UnsupportedInfo::*;
|
||||
use crate::ty::layout::{Size, Align};
|
||||
use syntax::ast::Mutability;
|
||||
use std::iter;
|
||||
|
|
@ -245,7 +244,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
|
|||
Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size])
|
||||
}
|
||||
// This includes the case where `offset` is out-of-bounds to begin with.
|
||||
None => err!(Unsupported(UnterminatedCString(ptr.erase_tag()))),
|
||||
None => err!(UnterminatedCString(ptr.erase_tag())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -447,7 +446,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
|
|||
if self.relocations(cx, ptr, size).is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
err!(Unsupported(ReadPointerAsBytes))
|
||||
err!(ReadPointerAsBytes)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +516,7 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
|
|||
self.undef_mask.is_range_defined(
|
||||
ptr.offset,
|
||||
ptr.offset + size,
|
||||
).or_else(|idx| err!(Unsupported(ReadUndefBytes(idx))))
|
||||
).or_else(|idx| err!(ReadUndefBytes(idx)))
|
||||
}
|
||||
|
||||
pub fn mark_definedness(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,47 @@
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! err {
|
||||
($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::$($tt)*.into()) };
|
||||
($($tt:tt)*) => {
|
||||
Err($crate::mir::interpret::InterpError::Unsupported(
|
||||
$crate::mir::interpret::UnsupportedInfo::$($tt)*
|
||||
).into())
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! err_inval {
|
||||
($($tt:tt)*) => {
|
||||
Err($crate::mir::interpret::InterpError::InvalidProgram(
|
||||
$crate::mir::interpret::InvalidProgramInfo::$($tt)*
|
||||
).into())
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! err_ub {
|
||||
($($tt:tt)*) => {
|
||||
Err($crate::mir::interpret::InterpError::UndefinedBehaviour(
|
||||
$crate::mir::interpret::UndefinedBehaviourInfo::$($tt)*
|
||||
).into())
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! err_panic {
|
||||
($($tt:tt)*) => {
|
||||
Err($crate::mir::interpret::InterpError::Panic(
|
||||
$crate::mir::interpret::PanicMessage::$($tt)*
|
||||
).into())
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! err_exhaust {
|
||||
($($tt:tt)*) => {
|
||||
Err($crate::mir::interpret::InterpError::ResourceExhaustion(
|
||||
$crate::mir::interpret::ResourceExhaustionInfo::$($tt)*
|
||||
).into())
|
||||
};
|
||||
}
|
||||
|
||||
mod error;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
use std::fmt::{self, Display};
|
||||
|
||||
use super::error::UnsupportedInfo::*;
|
||||
use crate::mir;
|
||||
use crate::ty::layout::{self, HasDataLayout, Size};
|
||||
use rustc_macros::HashStable;
|
||||
|
||||
use super::{
|
||||
AllocId, InterpResult, PanicMessage
|
||||
};
|
||||
use super::{AllocId, InterpResult};
|
||||
|
||||
/// Used by `check_in_alloc` to indicate context of check
|
||||
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
|
|
@ -77,13 +74,13 @@ pub trait PointerArithmetic: layout::HasDataLayout {
|
|||
#[inline]
|
||||
fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> {
|
||||
let (res, over) = self.overflowing_offset(val, i);
|
||||
if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) }
|
||||
if over { err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> {
|
||||
let (res, over) = self.overflowing_signed_offset(val, i128::from(i));
|
||||
if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) }
|
||||
if over { err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,11 +196,7 @@ impl<'tcx, Tag> Pointer<Tag> {
|
|||
msg: CheckInAllocMsg,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
if self.offset > allocation_size {
|
||||
err!(Unsupported(PointerOutOfBounds {
|
||||
ptr: self.erase_tag(),
|
||||
msg,
|
||||
allocation_size,
|
||||
}))
|
||||
err!(PointerOutOfBounds { ptr: self.erase_tag(),msg,allocation_size })
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ use std::fmt;
|
|||
use rustc_macros::HashStable;
|
||||
use rustc_apfloat::{Float, ieee::{Double, Single}};
|
||||
|
||||
use super::error::UnsupportedInfo::*;
|
||||
use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size, Align}, subst::SubstsRef};
|
||||
use crate::ty::PlaceholderConst;
|
||||
use crate::hir::def_id::DefId;
|
||||
|
|
@ -361,7 +360,7 @@ impl<'tcx, Tag> Scalar<Tag> {
|
|||
Scalar::check_data(data, size);
|
||||
Ok(data)
|
||||
}
|
||||
Scalar::Ptr(_) => err!(Unsupported(ReadPointerAsBytes)),
|
||||
Scalar::Ptr(_) => err!(ReadPointerAsBytes),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -374,8 +373,8 @@ impl<'tcx, Tag> Scalar<Tag> {
|
|||
#[inline]
|
||||
pub fn to_ptr(self) -> InterpResult<'tcx, Pointer<Tag>> {
|
||||
match self {
|
||||
Scalar::Raw { data: 0, .. } => err!(Unsupported(InvalidNullPointerUsage)),
|
||||
Scalar::Raw { .. } => err!(Unsupported(ReadBytesAsPointer)),
|
||||
Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage),
|
||||
Scalar::Raw { .. } => err!(ReadBytesAsPointer),
|
||||
Scalar::Ptr(p) => Ok(p),
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +406,7 @@ impl<'tcx, Tag> Scalar<Tag> {
|
|||
match self {
|
||||
Scalar::Raw { data: 0, size: 1 } => Ok(false),
|
||||
Scalar::Raw { data: 1, size: 1 } => Ok(true),
|
||||
_ => err!(Unsupported(InvalidBool)),
|
||||
_ => err!(InvalidBool),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +414,7 @@ impl<'tcx, Tag> Scalar<Tag> {
|
|||
let val = self.to_u32()?;
|
||||
match ::std::char::from_u32(val) {
|
||||
Some(c) => Ok(c),
|
||||
None => err!(Unsupported(InvalidChar(val as u128))),
|
||||
None => err!(InvalidChar(val as u128)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -538,7 +537,7 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
|
|||
pub fn not_undef(self) -> InterpResult<'static, Scalar<Tag>> {
|
||||
match self {
|
||||
ScalarMaybeUndef::Scalar(scalar) => Ok(scalar),
|
||||
ScalarMaybeUndef::Undef => err!(Unsupported(ReadUndefBytes(Size::from_bytes(0)))),
|
||||
ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -353,9 +353,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
ecx.goto_block(ret)?; // fully evaluated and done
|
||||
Ok(None)
|
||||
} else {
|
||||
err!(Unsupported(
|
||||
MachineError(format!("calling non-const function `{}`", instance))
|
||||
))
|
||||
err!(MachineError(format!("calling non-const function `{}`", instance)))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -415,7 +413,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
_tcx: TyCtxt<'tcx>,
|
||||
_def_id: DefId,
|
||||
) -> InterpResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>> {
|
||||
err!(Unsupported(ReadForeignStatic))
|
||||
err!(ReadForeignStatic)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_apfloat::{Float, FloatConvert};
|
|||
use rustc::mir::interpret::{
|
||||
Scalar, InterpResult, Pointer, PointerArithmetic, InterpError,
|
||||
};
|
||||
use rustc::mir::{CastKind, interpret::{UnsupportedInfo::*, InvalidProgramInfo::*}};
|
||||
use rustc::mir::{CastKind, interpret::{InvalidProgramInfo::*}};
|
||||
|
||||
|
||||
use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal};
|
||||
|
|
@ -200,7 +200,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
},
|
||||
|
||||
// Casts to bool are not permitted by rustc, no need to handle them here.
|
||||
_ => err!(Unsupported(Unimplemented(format!("int to {:?} cast", dest_layout.ty)))),
|
||||
_ => err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ use rustc::mir::interpret::{
|
|||
ErrorHandled,
|
||||
GlobalId, Scalar, Pointer, FrameInfo, AllocId,
|
||||
InterpResult, InterpError,
|
||||
truncate, sign_extend, UnsupportedInfo::*, InvalidProgramInfo::*,
|
||||
ResourceExhaustionInfo::*, UndefinedBehaviourInfo::*,
|
||||
truncate, sign_extend, InvalidProgramInfo::*,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
|
|
@ -136,7 +135,7 @@ pub enum LocalValue<Tag=(), Id=AllocId> {
|
|||
impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
|
||||
pub fn access(&self) -> InterpResult<'tcx, Operand<Tag>> {
|
||||
match self.value {
|
||||
LocalValue::Dead => err!(Unsupported(DeadLocal)),
|
||||
LocalValue::Dead => err!(DeadLocal),
|
||||
LocalValue::Uninitialized =>
|
||||
bug!("The type checker should prevent reading from a never-written local"),
|
||||
LocalValue::Live(val) => Ok(val),
|
||||
|
|
@ -149,7 +148,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> {
|
|||
&mut self,
|
||||
) -> InterpResult<'tcx, Result<&mut LocalValue<Tag>, MemPlace<Tag>>> {
|
||||
match self.value {
|
||||
LocalValue::Dead => err!(Unsupported(DeadLocal)),
|
||||
LocalValue::Dead => err!(DeadLocal),
|
||||
LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)),
|
||||
ref mut local @ LocalValue::Live(Operand::Immediate(_)) |
|
||||
ref mut local @ LocalValue::Uninitialized => {
|
||||
|
|
@ -303,7 +302,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
&substs,
|
||||
)),
|
||||
None => if substs.needs_subst() {
|
||||
err!(InvalidProgram(TooGeneric)).into()
|
||||
err_inval!(TooGeneric).into()
|
||||
} else {
|
||||
Ok(substs)
|
||||
},
|
||||
|
|
@ -337,14 +336,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
&& self.tcx.has_typeck_tables(did)
|
||||
&& self.tcx.typeck_tables_of(did).tainted_by_errors
|
||||
{
|
||||
return err!(InvalidProgram(TypeckError));
|
||||
return err_inval!(TypeckError);
|
||||
}
|
||||
trace!("load mir {:?}", instance);
|
||||
match instance {
|
||||
ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
|
||||
Ok(self.tcx.optimized_mir(did))
|
||||
} else {
|
||||
err!(Unsupported(NoMirFor(self.tcx.def_path_str(def_id))))
|
||||
err!(NoMirFor(self.tcx.def_path_str(def_id)))
|
||||
},
|
||||
_ => Ok(self.tcx.instance_mir(instance)),
|
||||
}
|
||||
|
|
@ -357,7 +356,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match self.stack.last() {
|
||||
Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)?),
|
||||
None => if t.needs_subst() {
|
||||
err!(InvalidProgram(TooGeneric)).into()
|
||||
err_inval!(TooGeneric).into()
|
||||
} else {
|
||||
Ok(t)
|
||||
},
|
||||
|
|
@ -374,7 +373,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let substituted = t.subst(*self.tcx, substs);
|
||||
|
||||
if substituted.needs_subst() {
|
||||
return err!(InvalidProgram(TooGeneric));
|
||||
return err_inval!(TooGeneric);
|
||||
}
|
||||
|
||||
Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted))
|
||||
|
|
@ -573,7 +572,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
|
||||
if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit {
|
||||
err!(ResourceExhaustion(StackFrameLimitReached))
|
||||
err_exhaust!(StackFrameLimitReached)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -621,7 +620,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
} else {
|
||||
// Uh, that shouldn't happen... the function did not intend to return
|
||||
return err!(UndefinedBehaviour(Unreachable));
|
||||
return err_ub!(Unreachable);
|
||||
}
|
||||
// Jump to new block -- *after* validation so that the spans make more sense.
|
||||
match frame.return_to_block {
|
||||
|
|
|
|||
|
|
@ -328,9 +328,7 @@ pub fn intern_const_alloc_recursive(
|
|||
}
|
||||
} else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) {
|
||||
// dangling pointer
|
||||
return err!(Unsupported(ValidationFailure(
|
||||
"encountered dangling pointer in final constant".into(),
|
||||
)))
|
||||
return err!(ValidationFailure("encountered dangling pointer in final constant".into()))
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -104,9 +104,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
};
|
||||
let out_val = if intrinsic_name.ends_with("_nonzero") {
|
||||
if bits == 0 {
|
||||
return err!(
|
||||
Unsupported(Intrinsic(format!("{} called on 0", intrinsic_name)))
|
||||
);
|
||||
return err!(Intrinsic(format!("{} called on 0", intrinsic_name)));
|
||||
}
|
||||
numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)?
|
||||
} else {
|
||||
|
|
@ -192,9 +190,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
if overflowed {
|
||||
let layout = self.layout_of(substs.type_at(0))?;
|
||||
let r_val = r.to_scalar()?.to_bits(layout.size)?;
|
||||
return err!(Unsupported(Intrinsic(
|
||||
return err!(Intrinsic(
|
||||
format!("Overflowing shift by {} in {}", r_val, intrinsic_name),
|
||||
)));
|
||||
));
|
||||
}
|
||||
self.write_scalar(val, dest)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
_mem: &Memory<'mir, 'tcx, Self>,
|
||||
_ptr: Pointer<Self::PointerTag>,
|
||||
) -> InterpResult<'tcx, u64> {
|
||||
err!(Unsupported(ReadPointerAsBytes))
|
||||
err!(ReadPointerAsBytes)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ impl<'tcx, Other> FnVal<'tcx, Other> {
|
|||
match self {
|
||||
FnVal::Instance(instance) =>
|
||||
Ok(instance),
|
||||
FnVal::Other(_) => err!(Unsupported(MachineError(format!(
|
||||
FnVal::Other(_) => err!(MachineError(format!(
|
||||
"Expected instance function pointer, got 'other' pointer"
|
||||
)))),
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +203,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
kind: MemoryKind<M::MemoryKinds>,
|
||||
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
|
||||
if ptr.offset.bytes() != 0 {
|
||||
return err!(Unsupported(ReallocateNonBasePtr));
|
||||
return err!(ReallocateNonBasePtr);
|
||||
}
|
||||
|
||||
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc".
|
||||
|
|
@ -244,7 +244,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
trace!("deallocating: {}", ptr.alloc_id);
|
||||
|
||||
if ptr.offset.bytes() != 0 {
|
||||
return err!(Unsupported(DeallocateNonBasePtr));
|
||||
return err!(DeallocateNonBasePtr);
|
||||
}
|
||||
|
||||
let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) {
|
||||
|
|
@ -252,33 +252,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
None => {
|
||||
// Deallocating static memory -- always an error
|
||||
return match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
|
||||
Some(GlobalAlloc::Function(..)) => err!(Unsupported(DeallocatedWrongMemoryKind(
|
||||
Some(GlobalAlloc::Function(..)) => err!(DeallocatedWrongMemoryKind(
|
||||
"function".to_string(),
|
||||
format!("{:?}", kind),
|
||||
))),
|
||||
)),
|
||||
Some(GlobalAlloc::Static(..)) |
|
||||
Some(GlobalAlloc::Memory(..)) => err!(Unsupported(DeallocatedWrongMemoryKind(
|
||||
Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind(
|
||||
"static".to_string(),
|
||||
format!("{:?}", kind),
|
||||
))),
|
||||
None => err!(Unsupported(DoubleFree))
|
||||
)),
|
||||
None => err!(DoubleFree)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if alloc_kind != kind {
|
||||
return err!(Unsupported(DeallocatedWrongMemoryKind(
|
||||
return err!(DeallocatedWrongMemoryKind(
|
||||
format!("{:?}", alloc_kind),
|
||||
format!("{:?}", kind),
|
||||
)));
|
||||
));
|
||||
}
|
||||
if let Some((size, align)) = old_size_and_align {
|
||||
if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align {
|
||||
let bytes = Size::from_bytes(alloc.bytes.len() as u64);
|
||||
return err!(Unsupported(IncorrectAllocationInformation(size,
|
||||
bytes,
|
||||
align,
|
||||
alloc.align)));
|
||||
return err!(IncorrectAllocationInformation(size, bytes, align, alloc.align));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -323,10 +320,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
} else {
|
||||
// The biggest power of two through which `offset` is divisible.
|
||||
let offset_pow2 = 1 << offset.trailing_zeros();
|
||||
err!(Unsupported(AlignmentCheckFailed {
|
||||
err!(AlignmentCheckFailed {
|
||||
has: Align::from_bytes(offset_pow2).unwrap(),
|
||||
required: align,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -345,7 +342,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
assert!(size.bytes() == 0);
|
||||
// Must be non-NULL and aligned.
|
||||
if bits == 0 {
|
||||
return err!(Unsupported(InvalidNullPointerUsage));
|
||||
return err!(InvalidNullPointerUsage);
|
||||
}
|
||||
check_offset_align(bits, align)?;
|
||||
None
|
||||
|
|
@ -366,10 +363,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
// got picked we might be aligned even if this check fails.
|
||||
// We instead have to fall back to converting to an integer and checking
|
||||
// the "real" alignment.
|
||||
return err!(Unsupported(AlignmentCheckFailed {
|
||||
return err!(AlignmentCheckFailed {
|
||||
has: alloc_align,
|
||||
required: align,
|
||||
}));
|
||||
});
|
||||
}
|
||||
check_offset_align(ptr.offset.bytes(), align)?;
|
||||
|
||||
|
|
@ -417,9 +414,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
Some(GlobalAlloc::Memory(mem)) =>
|
||||
Cow::Borrowed(mem),
|
||||
Some(GlobalAlloc::Function(..)) =>
|
||||
return err!(Unsupported(DerefFunctionPointer)),
|
||||
return err!(DerefFunctionPointer),
|
||||
None =>
|
||||
return err!(Unsupported(DanglingPointerDeref)),
|
||||
return err!(DanglingPointerDeref),
|
||||
Some(GlobalAlloc::Static(def_id)) => {
|
||||
// We got a "lazy" static that has not been computed yet.
|
||||
if tcx.is_foreign_item(def_id) {
|
||||
|
|
@ -507,11 +504,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
// to give us a cheap reference.
|
||||
let alloc = Self::get_static_alloc(memory_extra, tcx, id)?;
|
||||
if alloc.mutability == Mutability::Immutable {
|
||||
return err!(Unsupported(ModifiedConstantMemory));
|
||||
return err!(ModifiedConstantMemory);
|
||||
}
|
||||
match M::STATIC_KIND {
|
||||
Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())),
|
||||
None => err!(Unsupported(ModifiedStatic)),
|
||||
None => err!(ModifiedStatic),
|
||||
}
|
||||
});
|
||||
// Unpack the error type manually because type inference doesn't
|
||||
|
|
@ -521,7 +518,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
Ok(a) => {
|
||||
let a = &mut a.1;
|
||||
if a.mutability == Mutability::Immutable {
|
||||
return err!(Unsupported(ModifiedConstantMemory));
|
||||
return err!(ModifiedConstantMemory);
|
||||
}
|
||||
Ok(a)
|
||||
}
|
||||
|
|
@ -604,7 +601,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
|
||||
let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value.
|
||||
if ptr.offset.bytes() != 0 {
|
||||
return err!(Unsupported(InvalidFunctionPointer));
|
||||
return err!(InvalidFunctionPointer);
|
||||
}
|
||||
self.get_fn_alloc(ptr.alloc_id)
|
||||
}
|
||||
|
|
@ -839,9 +836,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
if (src.offset <= dest.offset && src.offset + size > dest.offset) ||
|
||||
(dest.offset <= src.offset && dest.offset + size > src.offset)
|
||||
{
|
||||
return err!(Unsupported(Intrinsic(
|
||||
return err!(Intrinsic(
|
||||
"copy_nonoverlapping called on overlapping ranges".to_string(),
|
||||
)));
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use rustc::mir::interpret::{
|
|||
GlobalId, AllocId,
|
||||
ConstValue, Pointer, Scalar,
|
||||
InterpResult, InterpError,
|
||||
sign_extend, truncate, UnsupportedInfo::*, InvalidProgramInfo::*
|
||||
sign_extend, truncate, UnsupportedInfo::*,
|
||||
};
|
||||
use super::{
|
||||
InterpCx, Machine,
|
||||
|
|
@ -460,7 +460,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
mir_place.iterate(|place_base, place_projection| {
|
||||
let mut op = match place_base {
|
||||
PlaceBase::Local(mir::RETURN_PLACE) =>
|
||||
return err!(Unsupported(ReadFromReturnPointer)),
|
||||
return err!(ReadFromReturnPointer),
|
||||
PlaceBase::Local(local) => {
|
||||
// Do not use the layout passed in as argument if the base we are looking at
|
||||
// here is not the entire place.
|
||||
|
|
@ -533,7 +533,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match val.val {
|
||||
ConstValue::Param(_) =>
|
||||
// FIXME(oli-obk): try to monomorphize
|
||||
return err!(InvalidProgram(TooGeneric)),
|
||||
return err_inval!(TooGeneric),
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
return Ok(OpTy::from(self.const_eval_raw(GlobalId {
|
||||
|
|
@ -608,7 +608,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
|
||||
Ok(raw_discr) => raw_discr,
|
||||
Err(_) =>
|
||||
return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag()))),
|
||||
return err!(InvalidDiscriminant(raw_discr.erase_tag())),
|
||||
};
|
||||
let real_discr = if discr_val.layout.ty.is_signed() {
|
||||
// going from layout tag type to typeck discriminant type
|
||||
|
|
@ -655,9 +655,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let ptr_valid = niche_start == 0 && variants_start == variants_end &&
|
||||
!self.memory.ptr_may_be_null(ptr);
|
||||
if !ptr_valid {
|
||||
return err!(Unsupported(InvalidDiscriminant(
|
||||
raw_discr.erase_tag().into()
|
||||
)));
|
||||
return err!(InvalidDiscriminant(raw_discr.erase_tag().into()));
|
||||
}
|
||||
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ use rustc::mir;
|
|||
use rustc::ty::{self, layout::TyLayout};
|
||||
use syntax::ast::FloatTy;
|
||||
use rustc_apfloat::Float;
|
||||
use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar};
|
||||
use rustc::mir::interpret::{InterpResult, Scalar};
|
||||
|
||||
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy, UnsupportedInfo::*};
|
||||
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
|
||||
|
||||
|
||||
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
|
@ -155,7 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
r,
|
||||
right_layout.ty
|
||||
);
|
||||
return err!(Unsupported(Unimplemented(msg)));
|
||||
return err!(Unimplemented(msg));
|
||||
}
|
||||
|
||||
// Operations that need special treatment for signed integers
|
||||
|
|
@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
return Ok((Scalar::from_bool(op(&l, &r)), false));
|
||||
}
|
||||
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
|
||||
Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
|
||||
Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)),
|
||||
Div if r == 0 => return err_panic!(DivisionByZero),
|
||||
Rem if r == 0 => return err_panic!(RemainderByZero),
|
||||
Div => Some(i128::overflowing_div),
|
||||
Rem => Some(i128::overflowing_rem),
|
||||
Add => Some(i128::overflowing_add),
|
||||
|
|
@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Add => u128::overflowing_add,
|
||||
Sub => u128::overflowing_sub,
|
||||
Mul => u128::overflowing_mul,
|
||||
Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)),
|
||||
Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)),
|
||||
Div if r == 0 => return err_panic!(DivisionByZero),
|
||||
Rem if r == 0 => return err_panic!(RemainderByZero),
|
||||
Div => u128::overflowing_div,
|
||||
Rem => u128::overflowing_rem,
|
||||
_ => bug!(),
|
||||
|
|
@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
r,
|
||||
right_layout.ty,
|
||||
);
|
||||
return err!(Unsupported(Unimplemented(msg)));
|
||||
return err!(Unimplemented(msg));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,8 @@ use rustc::ty::TypeFoldable;
|
|||
|
||||
use super::{
|
||||
GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
|
||||
InterpCx, Machine, AllocMap, AllocationExtra, PanicMessage,
|
||||
InterpCx, Machine, AllocMap, AllocationExtra,
|
||||
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue,
|
||||
UnsupportedInfo::*,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
|
|
@ -357,7 +356,7 @@ where
|
|||
// This can be violated because this runs during promotion on code where the
|
||||
// type system has not yet ensured that such things don't happen.
|
||||
debug!("tried to access element {} of array/slice with length {}", field, len);
|
||||
return err!(Panic(PanicMessage::BoundsCheck { len, index: field }));
|
||||
return err_panic!(BoundsCheck { len, index: field });
|
||||
}
|
||||
stride * field
|
||||
}
|
||||
|
|
@ -623,7 +622,7 @@ where
|
|||
.layout_of(self.monomorphize(self.frame().body.return_ty())?)?,
|
||||
}
|
||||
}
|
||||
None => return err!(Unsupported(InvalidNullPointerUsage)),
|
||||
None => return err!(InvalidNullPointerUsage),
|
||||
},
|
||||
PlaceBase::Local(local) => PlaceTy {
|
||||
// This works even for dead/uninitialized locals; we check further when writing
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic, UnsupportedInfo};
|
||||
use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic};
|
||||
|
||||
use super::{InterpCx, Machine};
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// size of MIR constantly.
|
||||
Nop => {}
|
||||
|
||||
InlineAsm { .. } => return err!(Unsupported(UnsupportedInfo::InlineAsm)),
|
||||
InlineAsm { .. } => return err!(InlineAsm),
|
||||
}
|
||||
|
||||
self.stack[frame_idx].stmt += 1;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rustc_target::spec::abi::Abi;
|
|||
use super::{
|
||||
InterpResult, PointerArithmetic, InterpError, Scalar,
|
||||
InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
|
||||
UndefinedBehaviourInfo, UnsupportedInfo::*,
|
||||
UnsupportedInfo::*,
|
||||
};
|
||||
|
||||
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
|
|
@ -20,7 +20,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
self.frame_mut().stmt = 0;
|
||||
Ok(())
|
||||
} else {
|
||||
err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable))
|
||||
err_ub!(Unreachable)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
},
|
||||
_ => {
|
||||
let msg = format!("can't handle callee of type {:?}", func.layout.ty);
|
||||
return err!(Unsupported(Unimplemented(msg)));
|
||||
return err!(Unimplemented(msg));
|
||||
}
|
||||
};
|
||||
let args = self.eval_operands(args)?;
|
||||
|
|
@ -145,20 +145,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let index = self.read_immediate(self.eval_operand(index, None)?)
|
||||
.expect("can't eval index").to_scalar()?
|
||||
.to_bits(self.memory().pointer_size())? as u64;
|
||||
err!(Panic(BoundsCheck { len, index }))
|
||||
err_panic!(BoundsCheck { len, index })
|
||||
}
|
||||
Overflow(op) =>
|
||||
err!(Panic(Overflow(*op))),
|
||||
err_panic!(Overflow(*op)),
|
||||
OverflowNeg =>
|
||||
err!(Panic(OverflowNeg)),
|
||||
err_panic!(OverflowNeg),
|
||||
DivisionByZero =>
|
||||
err!(Panic(DivisionByZero)),
|
||||
err_panic!(DivisionByZero),
|
||||
RemainderByZero =>
|
||||
err!(Panic(RemainderByZero)),
|
||||
err_panic!(RemainderByZero),
|
||||
GeneratorResumedAfterReturn =>
|
||||
err!(Panic(GeneratorResumedAfterReturn)),
|
||||
err_panic!(GeneratorResumedAfterReturn),
|
||||
GeneratorResumedAfterPanic =>
|
||||
err!(Panic(GeneratorResumedAfterPanic)),
|
||||
err_panic!(GeneratorResumedAfterPanic),
|
||||
Panic { .. } =>
|
||||
bug!("`Panic` variant cannot occur in MIR"),
|
||||
};
|
||||
|
|
@ -174,7 +174,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
`simplify_branches` mir pass"),
|
||||
FalseUnwind { .. } => bug!("should have been eliminated by\
|
||||
`simplify_branches` mir pass"),
|
||||
Unreachable => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)),
|
||||
Unreachable => return err_ub!(Unreachable),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -227,9 +227,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
// Now, check
|
||||
if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) {
|
||||
return err!(
|
||||
Unsupported(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty))
|
||||
);
|
||||
return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty));
|
||||
}
|
||||
// We allow some transmutes here
|
||||
self.copy_op_transmute(caller_arg, callee_arg)
|
||||
|
|
@ -257,13 +255,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match instance.def {
|
||||
ty::InstanceDef::Intrinsic(..) => {
|
||||
if caller_abi != Abi::RustIntrinsic {
|
||||
return err!(Unsupported(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)));
|
||||
return err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic));
|
||||
}
|
||||
// The intrinsic itself cannot diverge, so if we got here without a return
|
||||
// place... (can happen e.g., for transmute returning `!`)
|
||||
let dest = match dest {
|
||||
Some(dest) => dest,
|
||||
None => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable))
|
||||
None => return err_ub!(Unreachable)
|
||||
};
|
||||
M::call_intrinsic(self, instance, args, dest)?;
|
||||
// No stack frame gets pushed, the main loop will just act as if the
|
||||
|
|
@ -298,7 +296,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
abi,
|
||||
};
|
||||
if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
|
||||
return err!(Unsupported(FunctionAbiMismatch(caller_abi, callee_abi)));
|
||||
return err!(FunctionAbiMismatch(caller_abi, callee_abi));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,7 +391,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// Now we should have no more caller args
|
||||
if caller_iter.next().is_some() {
|
||||
trace!("Caller has passed too many args");
|
||||
return err!(Unsupported(FunctionArgCountMismatch));
|
||||
return err!(FunctionArgCountMismatch);
|
||||
}
|
||||
// Don't forget to check the return type!
|
||||
if let Some(caller_ret) = dest {
|
||||
|
|
@ -405,15 +403,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
caller_ret.layout,
|
||||
callee_ret.layout,
|
||||
) {
|
||||
return err!(Unsupported(
|
||||
return err!(
|
||||
FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty)
|
||||
));
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let local = mir::RETURN_PLACE;
|
||||
let ty = self.frame().body.local_decls[local].ty;
|
||||
if !self.tcx.is_ty_uninhabited_from_any_module(ty) {
|
||||
return err!(Unsupported(FunctionRetMismatch(self.tcx.types.never, ty)));
|
||||
return err!(FunctionRetMismatch(self.tcx.types.never, ty));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ macro_rules! validation_failure {
|
|||
} else {
|
||||
format!(" at {}", where_)
|
||||
};
|
||||
err!(Unsupported(ValidationFailure(format!(
|
||||
err!(ValidationFailure(format!(
|
||||
"encountered {}{}, but expected {}",
|
||||
$what, where_, $details,
|
||||
))))
|
||||
)))
|
||||
}};
|
||||
($what:expr, $where:expr) => {{
|
||||
let where_ = path_format(&$where);
|
||||
|
|
@ -34,10 +34,10 @@ macro_rules! validation_failure {
|
|||
} else {
|
||||
format!(" at {}", where_)
|
||||
};
|
||||
err!(Unsupported(ValidationFailure(format!(
|
||||
err!(ValidationFailure(format!(
|
||||
"encountered {}{}",
|
||||
$what, where_,
|
||||
))))
|
||||
)))
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -448,7 +448,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
// Need to do overflow check here: For actual CTFE, MIR
|
||||
// generation emits code that does this before calling the op.
|
||||
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
|
||||
return err!(Panic(PanicMessage::OverflowNeg));
|
||||
return err_panic!(OverflowNeg);
|
||||
}
|
||||
}
|
||||
UnOp::Not => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue