mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
fixing fallout due to InterpError refactor
This commit is contained in:
parent
4f0ab6ccce
commit
307798aa38
@ -4,6 +4,7 @@ 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;
|
||||
@ -244,7 +245,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!(UnterminatedCString(ptr.erase_tag())),
|
||||
None => err!(Unsupported(UnterminatedCString(ptr.erase_tag()))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,7 +447,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
|
||||
if self.relocations(cx, ptr, size).is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
err!(ReadPointerAsBytes)
|
||||
err!(Unsupported(ReadPointerAsBytes))
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,7 +517,7 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
|
||||
self.undef_mask.is_range_defined(
|
||||
ptr.offset,
|
||||
ptr.offset + size,
|
||||
).or_else(|idx| err!(ReadUndefBytes(idx)))
|
||||
).or_else(|idx| err!(Unsupported(ReadUndefBytes(idx))))
|
||||
}
|
||||
|
||||
pub fn mark_definedness(
|
||||
|
@ -142,7 +142,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
|
||||
InterpError::InvalidProgram(Layout(LayoutError::Unknown(_))) |
|
||||
InterpError::InvalidProgram(TooGeneric) =>
|
||||
return Err(ErrorHandled::TooGeneric),
|
||||
InterpError::Layout(LayoutError::SizeOverflow(_)) |
|
||||
InterpError::InvalidProgram(Layout(LayoutError::SizeOverflow(_))) |
|
||||
InterpError::InvalidProgram(TypeckError) =>
|
||||
return Err(ErrorHandled::Reported),
|
||||
_ => {},
|
||||
@ -325,16 +325,47 @@ pub enum InvalidProgramInfo<'tcx> {
|
||||
Layout(layout::LayoutError<'tcx>),
|
||||
}
|
||||
|
||||
impl fmt::Debug for InvalidProgramInfo<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use InvalidProgramInfo::*;
|
||||
match self {
|
||||
TooGeneric =>
|
||||
write!(f, "encountered overly generic constant"),
|
||||
ReferencedConstant =>
|
||||
write!(f, "referenced constant has errors"),
|
||||
TypeckError =>
|
||||
write!(f, "encountered constants with type errors, stopping evaluation"),
|
||||
Layout(ref err) =>
|
||||
write!(f, "rustc layout computation failed: {:?}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum UndefinedBehaviourInfo {
|
||||
/// Handle cases which for which we do not have a fixed variant
|
||||
/// Handle cases which for which we do not have a fixed variant.
|
||||
Ub(String),
|
||||
/// Unreachable code was executed.
|
||||
Unreachable,
|
||||
}
|
||||
|
||||
impl fmt::Debug for UndefinedBehaviourInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use UndefinedBehaviourInfo::*;
|
||||
match self {
|
||||
Ub(ref msg) =>
|
||||
write!(f, "{}", msg),
|
||||
Unreachable =>
|
||||
write!(f, "entered unreachable code"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum UnsupportedInfo<'tcx> {
|
||||
Unimplemented(String),
|
||||
|
||||
// -- Everything below is not classified yet --
|
||||
FunctionAbiMismatch(Abi, Abi),
|
||||
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
|
||||
FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>),
|
||||
@ -400,6 +431,19 @@ pub enum ResourceExhaustionInfo {
|
||||
InfiniteLoop,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ResourceExhaustionInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use ResourceExhaustionInfo::*;
|
||||
match self {
|
||||
StackFrameLimitReached =>
|
||||
write!(f, "reached the configured maximum number of stack frames"),
|
||||
InfiniteLoop =>
|
||||
write!(f, "duplicate interpreter state observed here, const evaluation will never \
|
||||
terminate"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum InterpError<'tcx> {
|
||||
/// The program panicked.
|
||||
@ -431,139 +475,131 @@ impl fmt::Display for InterpError<'_> {
|
||||
impl fmt::Debug for InterpError<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use InterpError::*;
|
||||
use UnsupportedInfo::*;
|
||||
match *self {
|
||||
PointerOutOfBounds { ptr, msg, allocation_size } => {
|
||||
Unsupported(PointerOutOfBounds { ptr, msg, allocation_size }) => {
|
||||
write!(f, "{} failed: pointer must be in-bounds at offset {}, \
|
||||
but is outside bounds of allocation {} which has size {}",
|
||||
msg, ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
|
||||
},
|
||||
ValidationFailure(ref err) => {
|
||||
Unsupported(ValidationFailure(ref err)) => {
|
||||
write!(f, "type validation failed: {}", err)
|
||||
}
|
||||
NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
|
||||
FunctionAbiMismatch(caller_abi, callee_abi) =>
|
||||
Unsupported(NoMirFor(ref func)) => write!(f, "no mir for `{}`", func),
|
||||
Unsupported(FunctionAbiMismatch(caller_abi, callee_abi)) =>
|
||||
write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}",
|
||||
callee_abi, caller_abi),
|
||||
FunctionArgMismatch(caller_ty, callee_ty) =>
|
||||
Unsupported(FunctionArgMismatch(caller_ty, callee_ty)) =>
|
||||
write!(f, "tried to call a function with argument of type {:?} \
|
||||
passing data of type {:?}",
|
||||
callee_ty, caller_ty),
|
||||
FunctionRetMismatch(caller_ty, callee_ty) =>
|
||||
Unsupported(FunctionRetMismatch(caller_ty, callee_ty)) =>
|
||||
write!(f, "tried to call a function with return type {:?} \
|
||||
passing return place of type {:?}",
|
||||
callee_ty, caller_ty),
|
||||
FunctionArgCountMismatch =>
|
||||
Unsupported(FunctionArgCountMismatch) =>
|
||||
write!(f, "tried to call a function with incorrect number of arguments"),
|
||||
ReallocatedWrongMemoryKind(ref old, ref new) =>
|
||||
Unsupported(ReallocatedWrongMemoryKind(ref old, ref new)) =>
|
||||
write!(f, "tried to reallocate memory from {} to {}", old, new),
|
||||
DeallocatedWrongMemoryKind(ref old, ref new) =>
|
||||
Unsupported(DeallocatedWrongMemoryKind(ref old, ref new)) =>
|
||||
write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
|
||||
InvalidChar(c) =>
|
||||
Unsupported(InvalidChar(c)) =>
|
||||
write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
|
||||
AlignmentCheckFailed { required, has } =>
|
||||
Unsupported(AlignmentCheckFailed { required, has }) =>
|
||||
write!(f, "tried to access memory with alignment {}, but alignment {} is required",
|
||||
has.bytes(), required.bytes()),
|
||||
TypeNotPrimitive(ty) =>
|
||||
Unsupported(TypeNotPrimitive(ty)) =>
|
||||
write!(f, "expected primitive type, got {}", ty),
|
||||
Layout(ref err) =>
|
||||
write!(f, "rustc layout computation failed: {:?}", err),
|
||||
PathNotFound(ref path) =>
|
||||
Unsupported(PathNotFound(ref path)) =>
|
||||
write!(f, "Cannot find path {:?}", path),
|
||||
IncorrectAllocationInformation(size, size2, align, align2) =>
|
||||
Unsupported(IncorrectAllocationInformation(size, size2, align, align2)) =>
|
||||
write!(f, "incorrect alloc info: expected size {} and align {}, \
|
||||
got size {} and align {}",
|
||||
size.bytes(), align.bytes(), size2.bytes(), align2.bytes()),
|
||||
InvalidDiscriminant(val) =>
|
||||
Unsupported(InvalidDiscriminant(val)) =>
|
||||
write!(f, "encountered invalid enum discriminant {}", val),
|
||||
Exit(code) =>
|
||||
write!(f, "exited with status code {}", code),
|
||||
InvalidMemoryAccess =>
|
||||
Unsupported(InvalidMemoryAccess) =>
|
||||
write!(f, "tried to access memory through an invalid pointer"),
|
||||
DanglingPointerDeref =>
|
||||
Unsupported(DanglingPointerDeref) =>
|
||||
write!(f, "dangling pointer was dereferenced"),
|
||||
DoubleFree =>
|
||||
Unsupported(DoubleFree) =>
|
||||
write!(f, "tried to deallocate dangling pointer"),
|
||||
InvalidFunctionPointer =>
|
||||
Unsupported(InvalidFunctionPointer) =>
|
||||
write!(f, "tried to use a function pointer after offsetting it"),
|
||||
InvalidBool =>
|
||||
Unsupported(InvalidBool) =>
|
||||
write!(f, "invalid boolean value read"),
|
||||
InvalidNullPointerUsage =>
|
||||
Unsupported(InvalidNullPointerUsage) =>
|
||||
write!(f, "invalid use of NULL pointer"),
|
||||
ReadPointerAsBytes =>
|
||||
Unsupported(ReadPointerAsBytes) =>
|
||||
write!(f, "a raw memory access tried to access part of a pointer value as raw \
|
||||
bytes"),
|
||||
ReadBytesAsPointer =>
|
||||
Unsupported(ReadBytesAsPointer) =>
|
||||
write!(f, "a memory access tried to interpret some bytes as a pointer"),
|
||||
ReadForeignStatic =>
|
||||
Unsupported(ReadForeignStatic) =>
|
||||
write!(f, "tried to read from foreign (extern) static"),
|
||||
InvalidPointerMath =>
|
||||
Unsupported(InvalidPointerMath) =>
|
||||
write!(f, "attempted to do invalid arithmetic on pointers that would leak base \
|
||||
addresses, e.g., comparing pointers into different allocations"),
|
||||
DeadLocal =>
|
||||
Unsupported(DeadLocal) =>
|
||||
write!(f, "tried to access a dead local variable"),
|
||||
DerefFunctionPointer =>
|
||||
Unsupported(DerefFunctionPointer) =>
|
||||
write!(f, "tried to dereference a function pointer"),
|
||||
ExecuteMemory =>
|
||||
Unsupported(ExecuteMemory) =>
|
||||
write!(f, "tried to treat a memory pointer as a function pointer"),
|
||||
StackFrameLimitReached =>
|
||||
write!(f, "reached the configured maximum number of stack frames"),
|
||||
OutOfTls =>
|
||||
Unsupported(OutOfTls) =>
|
||||
write!(f, "reached the maximum number of representable TLS keys"),
|
||||
TlsOutOfBounds =>
|
||||
Unsupported(TlsOutOfBounds) =>
|
||||
write!(f, "accessed an invalid (unallocated) TLS key"),
|
||||
CalledClosureAsFunction =>
|
||||
Unsupported(CalledClosureAsFunction) =>
|
||||
write!(f, "tried to call a closure through a function pointer"),
|
||||
VtableForArgumentlessMethod =>
|
||||
Unsupported(VtableForArgumentlessMethod) =>
|
||||
write!(f, "tried to call a vtable function without arguments"),
|
||||
ModifiedConstantMemory =>
|
||||
Unsupported(ModifiedConstantMemory) =>
|
||||
write!(f, "tried to modify constant memory"),
|
||||
ModifiedStatic =>
|
||||
Unsupported(ModifiedStatic) =>
|
||||
write!(f, "tried to modify a static's initial value from another static's \
|
||||
initializer"),
|
||||
AssumptionNotHeld =>
|
||||
Unsupported(AssumptionNotHeld) =>
|
||||
write!(f, "`assume` argument was false"),
|
||||
InlineAsm =>
|
||||
Unsupported(InlineAsm) =>
|
||||
write!(f, "miri does not support inline assembly"),
|
||||
ReallocateNonBasePtr =>
|
||||
Unsupported(ReallocateNonBasePtr) =>
|
||||
write!(f, "tried to reallocate with a pointer not to the beginning of an \
|
||||
existing object"),
|
||||
DeallocateNonBasePtr =>
|
||||
Unsupported(DeallocateNonBasePtr) =>
|
||||
write!(f, "tried to deallocate with a pointer not to the beginning of an \
|
||||
existing object"),
|
||||
HeapAllocZeroBytes =>
|
||||
Unsupported(HeapAllocZeroBytes) =>
|
||||
write!(f, "tried to re-, de- or allocate zero bytes on the heap"),
|
||||
Unreachable =>
|
||||
write!(f, "entered unreachable code"),
|
||||
ReadFromReturnPointer =>
|
||||
Unsupported(ReadFromReturnPointer) =>
|
||||
write!(f, "tried to read from the return pointer"),
|
||||
UnimplementedTraitSelection =>
|
||||
Unsupported(UnimplementedTraitSelection) =>
|
||||
write!(f, "there were unresolved type arguments during trait selection"),
|
||||
TypeckError =>
|
||||
write!(f, "encountered constants with type errors, stopping evaluation"),
|
||||
TooGeneric =>
|
||||
write!(f, "encountered overly generic constant"),
|
||||
ReferencedConstant =>
|
||||
write!(f, "referenced constant has errors"),
|
||||
InfiniteLoop =>
|
||||
write!(f, "duplicate interpreter state observed here, const evaluation will never \
|
||||
terminate"),
|
||||
InvalidBoolOp(_) =>
|
||||
Unsupported(InvalidBoolOp(_)) =>
|
||||
write!(f, "invalid boolean operation"),
|
||||
UnterminatedCString(_) =>
|
||||
Unsupported(UnterminatedCString(_)) =>
|
||||
write!(f, "attempted to get length of a null terminated string, but no null \
|
||||
found before end of allocation"),
|
||||
ReadUndefBytes(_) =>
|
||||
Unsupported(ReadUndefBytes(_)) =>
|
||||
write!(f, "attempted to read undefined bytes"),
|
||||
HeapAllocNonPowerOfTwoAlignment(_) =>
|
||||
Unsupported(HeapAllocNonPowerOfTwoAlignment(_)) =>
|
||||
write!(f, "tried to re-, de-, or allocate heap memory with alignment that is \
|
||||
not a power of two"),
|
||||
MachineError(ref msg) |
|
||||
Unimplemented(ref msg) |
|
||||
AbiViolation(ref msg) |
|
||||
Intrinsic(ref msg) =>
|
||||
Unsupported(MachineError(ref msg)) |
|
||||
Unsupported(Unimplemented(ref msg)) |
|
||||
Unsupported(AbiViolation(ref msg)) |
|
||||
Unsupported(Intrinsic(ref msg)) =>
|
||||
write!(f, "{}", msg),
|
||||
InvalidProgram(ref msg) =>
|
||||
write!(f, "{:?}", msg),
|
||||
UndefinedBehaviour(ref msg) =>
|
||||
write!(f, "{:?}", msg),
|
||||
ResourceExhaustion(ref msg) =>
|
||||
write!(f, "{:?}", msg),
|
||||
Panic(ref msg) =>
|
||||
write!(f, "{:?}", msg),
|
||||
Exit(code) =>
|
||||
write!(f, "exited with status code {}", code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,8 @@ mod pointer;
|
||||
|
||||
pub use self::error::{
|
||||
InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error,
|
||||
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage
|
||||
FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage, UnsupportedInfo,
|
||||
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviourInfo,
|
||||
};
|
||||
|
||||
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use super::error::UnsupportedInfo::*;
|
||||
use crate::mir;
|
||||
use crate::ty::layout::{self, HasDataLayout, Size};
|
||||
use rustc_macros::HashStable;
|
||||
@ -198,11 +199,11 @@ impl<'tcx, Tag> Pointer<Tag> {
|
||||
msg: CheckInAllocMsg,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
if self.offset > allocation_size {
|
||||
err!(PointerOutOfBounds {
|
||||
err!(Unsupported(PointerOutOfBounds {
|
||||
ptr: self.erase_tag(),
|
||||
msg,
|
||||
allocation_size,
|
||||
})
|
||||
}))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ 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;
|
||||
@ -360,7 +361,7 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
Scalar::check_data(data, size);
|
||||
Ok(data)
|
||||
}
|
||||
Scalar::Ptr(_) => err!(ReadPointerAsBytes),
|
||||
Scalar::Ptr(_) => err!(Unsupported(ReadPointerAsBytes)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,8 +374,8 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
#[inline]
|
||||
pub fn to_ptr(self) -> InterpResult<'tcx, Pointer<Tag>> {
|
||||
match self {
|
||||
Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage),
|
||||
Scalar::Raw { .. } => err!(ReadBytesAsPointer),
|
||||
Scalar::Raw { data: 0, .. } => err!(Unsupported(InvalidNullPointerUsage)),
|
||||
Scalar::Raw { .. } => err!(Unsupported(ReadBytesAsPointer)),
|
||||
Scalar::Ptr(p) => Ok(p),
|
||||
}
|
||||
}
|
||||
@ -406,7 +407,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!(InvalidBool),
|
||||
_ => err!(Unsupported(InvalidBool)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,7 +415,7 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
let val = self.to_u32()?;
|
||||
match ::std::char::from_u32(val) {
|
||||
Some(c) => Ok(c),
|
||||
None => err!(InvalidChar(val as u128)),
|
||||
None => err!(Unsupported(InvalidChar(val as u128))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,7 +538,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!(ReadUndefBytes(Size::from_bytes(0))),
|
||||
ScalarMaybeUndef::Undef => err!(Unsupported(ReadUndefBytes(Size::from_bytes(0)))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ use crate::interpret::{self,
|
||||
RawConst, ConstValue,
|
||||
InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup,
|
||||
Allocation, AllocId, MemoryKind,
|
||||
snapshot, RefTracking, intern_const_alloc_recursive,
|
||||
snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedInfo::*,
|
||||
InvalidProgramInfo::*,
|
||||
};
|
||||
|
||||
/// Number of steps until the detector even starts doing anything.
|
||||
@ -183,7 +184,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||
|
||||
impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalError {
|
||||
fn into(self) -> InterpErrorInfo<'tcx> {
|
||||
InterpError::MachineError(self.to_string()).into()
|
||||
InterpError::Unsupported(MachineError(self.to_string())).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,7 +353,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
ecx.goto_block(ret)?; // fully evaluated and done
|
||||
Ok(None)
|
||||
} else {
|
||||
err!(MachineError(format!("calling non-const function `{}`", instance)))
|
||||
err!(Unsupported(
|
||||
MachineError(format!("calling non-const function `{}`", instance))
|
||||
))
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -360,7 +363,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
Ok(Some(match ecx.load_mir(instance.def) {
|
||||
Ok(body) => body,
|
||||
Err(err) => {
|
||||
if let InterpError::NoMirFor(ref path) = err.kind {
|
||||
if let InterpError::Unsupported(NoMirFor(ref path)) = err.kind {
|
||||
return Err(
|
||||
ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path))
|
||||
.into(),
|
||||
@ -412,7 +415,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!(ReadForeignStatic)
|
||||
err!(Unsupported(ReadForeignStatic))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -698,7 +701,7 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||
// any other kind of error will be reported to the user as a deny-by-default lint
|
||||
_ => if let Some(p) = cid.promoted {
|
||||
let span = tcx.promoted_mir(def_id)[p].span;
|
||||
if let InterpError::ReferencedConstant = err.error {
|
||||
if let InterpError::InvalidProgram(ReferencedConstant) = err.error {
|
||||
err.report_as_error(
|
||||
tcx.at(span),
|
||||
"evaluation of constant expression failed",
|
||||
|
@ -9,7 +9,8 @@ use rustc_apfloat::{Float, FloatConvert};
|
||||
use rustc::mir::interpret::{
|
||||
Scalar, InterpResult, Pointer, PointerArithmetic, InterpError,
|
||||
};
|
||||
use rustc::mir::CastKind;
|
||||
use rustc::mir::{CastKind, interpret::{UnsupportedInfo::*, InvalidProgramInfo::*}};
|
||||
|
||||
|
||||
use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal};
|
||||
|
||||
@ -85,7 +86,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| InterpError::TooGeneric.into());
|
||||
).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into());
|
||||
let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance?));
|
||||
self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?;
|
||||
}
|
||||
@ -199,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!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))),
|
||||
_ => err!(Unsupported(Unimplemented(format!("int to {:?} cast", dest_layout.ty)))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,8 @@ use rustc::mir::interpret::{
|
||||
ErrorHandled,
|
||||
GlobalId, Scalar, Pointer, FrameInfo, AllocId,
|
||||
InterpResult, InterpError,
|
||||
truncate, sign_extend,
|
||||
truncate, sign_extend, UnsupportedInfo::*, InvalidProgramInfo::*,
|
||||
ResourceExhaustionInfo::*, UndefinedBehaviourInfo::*,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
@ -135,7 +136,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!(DeadLocal),
|
||||
LocalValue::Dead => err!(Unsupported(DeadLocal)),
|
||||
LocalValue::Uninitialized =>
|
||||
bug!("The type checker should prevent reading from a never-written local"),
|
||||
LocalValue::Live(val) => Ok(val),
|
||||
@ -148,7 +149,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!(DeadLocal),
|
||||
LocalValue::Dead => err!(Unsupported(DeadLocal)),
|
||||
LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)),
|
||||
ref mut local @ LocalValue::Live(Operand::Immediate(_)) |
|
||||
ref mut local @ LocalValue::Uninitialized => {
|
||||
@ -191,7 +192,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> {
|
||||
#[inline]
|
||||
fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
self.tcx.layout_of(self.param_env.and(ty))
|
||||
.map_err(|layout| InterpError::Layout(layout).into())
|
||||
.map_err(|layout| InterpError::InvalidProgram(Layout(layout)).into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,7 +303,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
&substs,
|
||||
)),
|
||||
None => if substs.needs_subst() {
|
||||
err!(TooGeneric).into()
|
||||
err!(InvalidProgram(TooGeneric)).into()
|
||||
} else {
|
||||
Ok(substs)
|
||||
},
|
||||
@ -323,7 +324,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| InterpError::TooGeneric.into())
|
||||
).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into())
|
||||
}
|
||||
|
||||
pub fn load_mir(
|
||||
@ -336,14 +337,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!(TypeckError);
|
||||
return err!(InvalidProgram(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!(NoMirFor(self.tcx.def_path_str(def_id)))
|
||||
err!(Unsupported(NoMirFor(self.tcx.def_path_str(def_id))))
|
||||
},
|
||||
_ => Ok(self.tcx.instance_mir(instance)),
|
||||
}
|
||||
@ -356,7 +357,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!(TooGeneric).into()
|
||||
err!(InvalidProgram(TooGeneric)).into()
|
||||
} else {
|
||||
Ok(t)
|
||||
},
|
||||
@ -373,7 +374,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!(TooGeneric);
|
||||
return err!(InvalidProgram(TooGeneric));
|
||||
}
|
||||
|
||||
Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted))
|
||||
@ -572,7 +573,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!(StackFrameLimitReached)
|
||||
err!(ResourceExhaustion(StackFrameLimitReached))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@ -620,7 +621,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!(Unreachable);
|
||||
return err!(UndefinedBehaviour(Unreachable));
|
||||
}
|
||||
// Jump to new block -- *after* validation so that the spans make more sense.
|
||||
match frame.return_to_block {
|
||||
@ -694,8 +695,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
// `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
|
||||
let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
|
||||
match err {
|
||||
ErrorHandled::Reported => InterpError::ReferencedConstant,
|
||||
ErrorHandled::TooGeneric => InterpError::TooGeneric,
|
||||
ErrorHandled::Reported => InterpError::InvalidProgram(ReferencedConstant),
|
||||
ErrorHandled::TooGeneric => InterpError::InvalidProgram(TooGeneric),
|
||||
}
|
||||
})?;
|
||||
self.raw_const_to_mplace(val)
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
use rustc::ty::{Ty, TyCtxt, ParamEnv, self};
|
||||
use rustc::mir::interpret::{
|
||||
InterpResult, ErrorHandled,
|
||||
InterpResult, ErrorHandled, UnsupportedInfo::*,
|
||||
};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
@ -293,7 +293,7 @@ pub fn intern_const_alloc_recursive(
|
||||
if let Err(error) = interned {
|
||||
// This can happen when e.g. the tag of an enum is not a valid discriminant. We do have
|
||||
// to read enum discriminants in order to find references in enum variant fields.
|
||||
if let InterpError::ValidationFailure(_) = error.kind {
|
||||
if let InterpError::Unsupported(ValidationFailure(_)) = error.kind {
|
||||
let err = crate::const_eval::error_to_const_error(&ecx, error);
|
||||
match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") {
|
||||
Ok(mut diag) => {
|
||||
@ -328,9 +328,9 @@ pub fn intern_const_alloc_recursive(
|
||||
}
|
||||
} else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) {
|
||||
// dangling pointer
|
||||
return err!(ValidationFailure(
|
||||
return err!(Unsupported(ValidationFailure(
|
||||
"encountered dangling pointer in final constant".into(),
|
||||
))
|
||||
)))
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -7,7 +7,7 @@ use rustc::ty;
|
||||
use rustc::ty::layout::{LayoutOf, Primitive, Size};
|
||||
use rustc::mir::BinOp;
|
||||
use rustc::mir::interpret::{
|
||||
InterpResult, InterpError, Scalar, PanicMessage,
|
||||
InterpResult, InterpError, Scalar, PanicMessage, UnsupportedInfo::*,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -100,11 +100,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?;
|
||||
let kind = match layout_of.abi {
|
||||
ty::layout::Abi::Scalar(ref scalar) => scalar.value,
|
||||
_ => Err(::rustc::mir::interpret::InterpError::TypeNotPrimitive(ty))?,
|
||||
_ => Err(InterpError::Unsupported(TypeNotPrimitive(ty)))?,
|
||||
};
|
||||
let out_val = if intrinsic_name.ends_with("_nonzero") {
|
||||
if bits == 0 {
|
||||
return err!(Intrinsic(format!("{} called on 0", intrinsic_name)));
|
||||
return err!(
|
||||
Unsupported(Intrinsic(format!("{} called on 0", intrinsic_name)))
|
||||
);
|
||||
}
|
||||
numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)?
|
||||
} else {
|
||||
@ -190,9 +192,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!(Intrinsic(
|
||||
return err!(Unsupported(Intrinsic(
|
||||
format!("Overflowing shift by {} in {}", r_val, intrinsic_name),
|
||||
));
|
||||
)));
|
||||
}
|
||||
self.write_scalar(val, dest)?;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use rustc::ty::{self, TyCtxt};
|
||||
|
||||
use super::{
|
||||
Allocation, AllocId, InterpResult, InterpError, Scalar, AllocationExtra,
|
||||
InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory,
|
||||
InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedInfo::*
|
||||
};
|
||||
|
||||
/// Whether this kind of memory is allowed to leak
|
||||
@ -240,9 +240,9 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||
int: u64,
|
||||
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
|
||||
Err((if int == 0 {
|
||||
InterpError::InvalidNullPointerUsage
|
||||
InterpError::Unsupported(InvalidNullPointerUsage)
|
||||
} else {
|
||||
InterpError::ReadBytesAsPointer
|
||||
InterpError::Unsupported(ReadBytesAsPointer)
|
||||
}).into())
|
||||
}
|
||||
|
||||
@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||
_mem: &Memory<'mir, 'tcx, Self>,
|
||||
_ptr: Pointer<Self::PointerTag>,
|
||||
) -> InterpResult<'tcx, u64> {
|
||||
err!(ReadPointerAsBytes)
|
||||
err!(Unsupported(ReadPointerAsBytes))
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ use syntax::ast::Mutability;
|
||||
use super::{
|
||||
Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
|
||||
InterpResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic,
|
||||
Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg,
|
||||
Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, UnsupportedInfo::*,
|
||||
InvalidProgramInfo::*
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
|
||||
@ -66,10 +67,9 @@ impl<'tcx, Other> FnVal<'tcx, Other> {
|
||||
match self {
|
||||
FnVal::Instance(instance) =>
|
||||
Ok(instance),
|
||||
FnVal::Other(_) =>
|
||||
err!(MachineError(
|
||||
format!("Expected instance function pointer, got 'other' pointer")
|
||||
)),
|
||||
FnVal::Other(_) => err!(Unsupported(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!(ReallocateNonBasePtr);
|
||||
return err!(Unsupported(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!(DeallocateNonBasePtr);
|
||||
return err!(Unsupported(DeallocateNonBasePtr));
|
||||
}
|
||||
|
||||
let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) {
|
||||
@ -252,33 +252,33 @@ 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!(DeallocatedWrongMemoryKind(
|
||||
Some(GlobalAlloc::Function(..)) => err!(Unsupported(DeallocatedWrongMemoryKind(
|
||||
"function".to_string(),
|
||||
format!("{:?}", kind),
|
||||
)),
|
||||
))),
|
||||
Some(GlobalAlloc::Static(..)) |
|
||||
Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind(
|
||||
Some(GlobalAlloc::Memory(..)) => err!(Unsupported(DeallocatedWrongMemoryKind(
|
||||
"static".to_string(),
|
||||
format!("{:?}", kind),
|
||||
)),
|
||||
None => err!(DoubleFree)
|
||||
))),
|
||||
None => err!(Unsupported(DoubleFree))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if alloc_kind != kind {
|
||||
return err!(DeallocatedWrongMemoryKind(
|
||||
return err!(Unsupported(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!(IncorrectAllocationInformation(size,
|
||||
return err!(Unsupported(IncorrectAllocationInformation(size,
|
||||
bytes,
|
||||
align,
|
||||
alloc.align));
|
||||
alloc.align)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,10 +323,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!(AlignmentCheckFailed {
|
||||
err!(Unsupported(AlignmentCheckFailed {
|
||||
has: Align::from_bytes(offset_pow2).unwrap(),
|
||||
required: align,
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,7 +345,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!(InvalidNullPointerUsage);
|
||||
return err!(Unsupported(InvalidNullPointerUsage));
|
||||
}
|
||||
check_offset_align(bits, align)?;
|
||||
None
|
||||
@ -366,10 +366,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!(AlignmentCheckFailed {
|
||||
return err!(Unsupported(AlignmentCheckFailed {
|
||||
has: alloc_align,
|
||||
required: align,
|
||||
});
|
||||
}));
|
||||
}
|
||||
check_offset_align(ptr.offset.bytes(), align)?;
|
||||
|
||||
@ -417,9 +417,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||
Some(GlobalAlloc::Memory(mem)) =>
|
||||
Cow::Borrowed(mem),
|
||||
Some(GlobalAlloc::Function(..)) =>
|
||||
return err!(DerefFunctionPointer),
|
||||
return err!(Unsupported(DerefFunctionPointer)),
|
||||
None =>
|
||||
return err!(DanglingPointerDeref),
|
||||
return err!(Unsupported(DanglingPointerDeref)),
|
||||
Some(GlobalAlloc::Static(def_id)) => {
|
||||
// We got a "lazy" static that has not been computed yet.
|
||||
if tcx.is_foreign_item(def_id) {
|
||||
@ -440,8 +440,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||
// for statics
|
||||
assert!(tcx.is_static(def_id));
|
||||
match err {
|
||||
ErrorHandled::Reported => InterpError::ReferencedConstant,
|
||||
ErrorHandled::TooGeneric => InterpError::TooGeneric,
|
||||
ErrorHandled::Reported =>
|
||||
InterpError::InvalidProgram(ReferencedConstant),
|
||||
ErrorHandled::TooGeneric =>
|
||||
InterpError::InvalidProgram(TooGeneric),
|
||||
}
|
||||
})?;
|
||||
// Make sure we use the ID of the resolved memory, not the lazy one!
|
||||
@ -505,11 +507,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!(ModifiedConstantMemory);
|
||||
return err!(Unsupported(ModifiedConstantMemory));
|
||||
}
|
||||
match M::STATIC_KIND {
|
||||
Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())),
|
||||
None => err!(ModifiedStatic),
|
||||
None => err!(Unsupported(ModifiedStatic)),
|
||||
}
|
||||
});
|
||||
// Unpack the error type manually because type inference doesn't
|
||||
@ -519,7 +521,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!(ModifiedConstantMemory);
|
||||
return err!(Unsupported(ModifiedConstantMemory));
|
||||
}
|
||||
Ok(a)
|
||||
}
|
||||
@ -591,7 +593,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||
} else {
|
||||
match self.tcx.alloc_map.lock().get(id) {
|
||||
Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)),
|
||||
_ => Err(InterpError::ExecuteMemory.into()),
|
||||
_ => Err(InterpError::Unsupported(ExecuteMemory).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -602,7 +604,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!(InvalidFunctionPointer);
|
||||
return err!(Unsupported(InvalidFunctionPointer));
|
||||
}
|
||||
self.get_fn_alloc(ptr.alloc_id)
|
||||
}
|
||||
@ -837,9 +839,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!(Intrinsic(
|
||||
return err!(Unsupported(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,
|
||||
sign_extend, truncate, UnsupportedInfo::*, InvalidProgramInfo::*
|
||||
};
|
||||
use super::{
|
||||
InterpCx, Machine,
|
||||
@ -332,7 +332,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let len = mplace.len(self)?;
|
||||
let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?;
|
||||
let str = ::std::str::from_utf8(bytes)
|
||||
.map_err(|err| InterpError::ValidationFailure(err.to_string()))?;
|
||||
.map_err(|err| InterpError::Unsupported(ValidationFailure(err.to_string())))?;
|
||||
Ok(str)
|
||||
}
|
||||
|
||||
@ -459,7 +459,8 @@ 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!(ReadFromReturnPointer),
|
||||
PlaceBase::Local(mir::RETURN_PLACE) =>
|
||||
return err!(Unsupported(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.
|
||||
@ -530,7 +531,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
};
|
||||
// Early-return cases.
|
||||
match val.val {
|
||||
ConstValue::Param(_) => return err!(TooGeneric), // FIXME(oli-obk): try to monomorphize
|
||||
ConstValue::Param(_) =>
|
||||
// FIXME(oli-obk): try to monomorphize
|
||||
return err!(InvalidProgram(TooGeneric)),
|
||||
ConstValue::Unevaluated(def_id, substs) => {
|
||||
let instance = self.resolve(def_id, substs)?;
|
||||
return Ok(OpTy::from(self.const_eval_raw(GlobalId {
|
||||
@ -604,7 +607,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
layout::DiscriminantKind::Tag => {
|
||||
let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
|
||||
Ok(raw_discr) => raw_discr,
|
||||
Err(_) => return err!(InvalidDiscriminant(raw_discr.erase_tag())),
|
||||
Err(_) =>
|
||||
return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag()))),
|
||||
};
|
||||
let real_discr = if discr_val.layout.ty.is_signed() {
|
||||
// going from layout tag type to typeck discriminant type
|
||||
@ -630,7 +634,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
.discriminants(*def_id, self.tcx.tcx)
|
||||
.find(|(_, var)| var.val == real_discr),
|
||||
_ => bug!("tagged layout for non-adt non-generator"),
|
||||
}.ok_or_else(|| InterpError::InvalidDiscriminant(raw_discr.erase_tag()))?;
|
||||
}.ok_or_else(
|
||||
|| InterpError::Unsupported(InvalidDiscriminant(raw_discr.erase_tag()))
|
||||
)?;
|
||||
(real_discr, index.0)
|
||||
},
|
||||
layout::DiscriminantKind::Niche {
|
||||
@ -641,14 +647,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let variants_start = niche_variants.start().as_u32() as u128;
|
||||
let variants_end = niche_variants.end().as_u32() as u128;
|
||||
let raw_discr = raw_discr.not_undef()
|
||||
.map_err(|_| InterpError::InvalidDiscriminant(ScalarMaybeUndef::Undef))?;
|
||||
.map_err(|_| InterpError::Unsupported(InvalidDiscriminant(ScalarMaybeUndef::Undef)))?;
|
||||
match raw_discr.to_bits_or_ptr(discr_val.layout.size, self) {
|
||||
Err(ptr) => {
|
||||
// The niche must be just 0 (which an inbounds pointer value never is)
|
||||
let ptr_valid = niche_start == 0 && variants_start == variants_end &&
|
||||
!self.memory.ptr_may_be_null(ptr);
|
||||
if !ptr_valid {
|
||||
return err!(InvalidDiscriminant(raw_discr.erase_tag().into()));
|
||||
return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag().into())));
|
||||
}
|
||||
(dataful_variant.as_u32() as u128, dataful_variant)
|
||||
},
|
||||
|
@ -4,7 +4,7 @@ use syntax::ast::FloatTy;
|
||||
use rustc_apfloat::Float;
|
||||
use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar};
|
||||
|
||||
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy};
|
||||
use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy, UnsupportedInfo::*};
|
||||
|
||||
|
||||
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!(Unimplemented(msg));
|
||||
return err!(Unsupported(Unimplemented(msg)));
|
||||
}
|
||||
|
||||
// Operations that need special treatment for signed integers
|
||||
@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
r,
|
||||
right_layout.ty,
|
||||
);
|
||||
return err!(Unimplemented(msg));
|
||||
return err!(Unsupported(Unimplemented(msg)));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,8 @@ use rustc::ty::TypeFoldable;
|
||||
use super::{
|
||||
GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic,
|
||||
InterpCx, Machine, AllocMap, AllocationExtra, PanicMessage,
|
||||
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue
|
||||
RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue,
|
||||
UnsupportedInfo::*,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
@ -622,7 +623,7 @@ where
|
||||
.layout_of(self.monomorphize(self.frame().body.return_ty())?)?,
|
||||
}
|
||||
}
|
||||
None => return err!(InvalidNullPointerUsage),
|
||||
None => return err!(Unsupported(InvalidNullPointerUsage)),
|
||||
},
|
||||
PlaceBase::Local(local) => PlaceTy {
|
||||
// This works even for dead/uninitialized locals; we check further when writing
|
||||
|
@ -12,7 +12,7 @@ use rustc::mir;
|
||||
use rustc::mir::interpret::{
|
||||
AllocId, Pointer, Scalar,
|
||||
Relocations, Allocation, UndefMask,
|
||||
InterpResult, InterpError,
|
||||
InterpResult, InterpError, ResourceExhaustionInfo::*,
|
||||
};
|
||||
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
@ -77,7 +77,7 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
// Second cycle
|
||||
Err(InterpError::InfiniteLoop.into())
|
||||
Err(InterpError::ResourceExhaustion(InfiniteLoop).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic};
|
||||
use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic, UnsupportedInfo};
|
||||
|
||||
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!(InlineAsm),
|
||||
InlineAsm { .. } => return err!(Unsupported(UnsupportedInfo::InlineAsm)),
|
||||
}
|
||||
|
||||
self.stack[frame_idx].stmt += 1;
|
||||
|
@ -9,6 +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::*,
|
||||
};
|
||||
|
||||
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
@ -19,7 +20,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.frame_mut().stmt = 0;
|
||||
Ok(())
|
||||
} else {
|
||||
err!(Unreachable)
|
||||
err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable))
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,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!(Unimplemented(msg));
|
||||
return err!(Unsupported(Unimplemented(msg)));
|
||||
}
|
||||
};
|
||||
let args = self.eval_operands(args)?;
|
||||
@ -173,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!(Unreachable),
|
||||
Unreachable => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -220,13 +221,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
return Ok(());
|
||||
}
|
||||
let caller_arg = caller_arg.next()
|
||||
.ok_or_else(|| InterpError::FunctionArgCountMismatch)?;
|
||||
.ok_or_else(|| InterpError::Unsupported(FunctionArgCountMismatch))?;
|
||||
if rust_abi {
|
||||
debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
|
||||
}
|
||||
// Now, check
|
||||
if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) {
|
||||
return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty));
|
||||
return err!(
|
||||
Unsupported(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty))
|
||||
);
|
||||
}
|
||||
// We allow some transmutes here
|
||||
self.copy_op_transmute(caller_arg, callee_arg)
|
||||
@ -254,13 +257,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!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic));
|
||||
return err!(Unsupported(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!(Unreachable)
|
||||
None => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable))
|
||||
};
|
||||
M::call_intrinsic(self, instance, args, dest)?;
|
||||
// No stack frame gets pushed, the main loop will just act as if the
|
||||
@ -295,7 +298,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
abi,
|
||||
};
|
||||
if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
|
||||
return err!(FunctionAbiMismatch(caller_abi, callee_abi));
|
||||
return err!(Unsupported(FunctionAbiMismatch(caller_abi, callee_abi)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,7 +393,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!(FunctionArgCountMismatch);
|
||||
return err!(Unsupported(FunctionArgCountMismatch));
|
||||
}
|
||||
// Don't forget to check the return type!
|
||||
if let Some(caller_ret) = dest {
|
||||
@ -402,15 +405,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
caller_ret.layout,
|
||||
callee_ret.layout,
|
||||
) {
|
||||
return err!(FunctionRetMismatch(
|
||||
caller_ret.layout.ty, callee_ret.layout.ty
|
||||
return err!(Unsupported(
|
||||
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!(FunctionRetMismatch(self.tcx.types.never, ty));
|
||||
return err!(Unsupported(FunctionRetMismatch(self.tcx.types.never, ty)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc::ty::{self, Ty, Instance};
|
||||
use rustc::ty::layout::{Size, Align, LayoutOf};
|
||||
use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic};
|
||||
use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic, InvalidProgramInfo};
|
||||
|
||||
use super::{InterpCx, InterpError, Machine, MemoryKind, FnVal};
|
||||
|
||||
@ -83,7 +83,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
self.param_env,
|
||||
def_id,
|
||||
substs,
|
||||
).ok_or_else(|| InterpError::TooGeneric)?;
|
||||
).ok_or_else(|| InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric))?;
|
||||
let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
|
||||
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?;
|
||||
self.memory
|
||||
|
@ -11,7 +11,7 @@ use std::hash::Hash;
|
||||
|
||||
use super::{
|
||||
GlobalAlloc, InterpResult, InterpError,
|
||||
OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
|
||||
OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedInfo::*,
|
||||
};
|
||||
|
||||
macro_rules! validation_failure {
|
||||
@ -22,10 +22,10 @@ macro_rules! validation_failure {
|
||||
} else {
|
||||
format!(" at {}", where_)
|
||||
};
|
||||
err!(ValidationFailure(format!(
|
||||
err!(Unsupported(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!(ValidationFailure(format!(
|
||||
err!(Unsupported(ValidationFailure(format!(
|
||||
"encountered {}{}",
|
||||
$what, where_,
|
||||
)))
|
||||
))))
|
||||
}};
|
||||
}
|
||||
|
||||
@ -297,11 +297,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||
match self.walk_value(op) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(err) => match err.kind {
|
||||
InterpError::InvalidDiscriminant(val) =>
|
||||
InterpError::Unsupported(InvalidDiscriminant(val)) =>
|
||||
validation_failure!(
|
||||
val, self.path, "a valid enum discriminant"
|
||||
),
|
||||
InterpError::ReadPointerAsBytes =>
|
||||
InterpError::Unsupported(ReadPointerAsBytes) =>
|
||||
validation_failure!(
|
||||
"a pointer", self.path, "plain (non-pointer) bytes"
|
||||
),
|
||||
@ -406,13 +406,13 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||
ptr, size, align
|
||||
);
|
||||
match err.kind {
|
||||
InterpError::InvalidNullPointerUsage =>
|
||||
InterpError::Unsupported(InvalidNullPointerUsage) =>
|
||||
return validation_failure!("NULL reference", self.path),
|
||||
InterpError::AlignmentCheckFailed { required, has } =>
|
||||
InterpError::Unsupported(AlignmentCheckFailed { required, has }) =>
|
||||
return validation_failure!(format!("unaligned reference \
|
||||
(required {} byte alignment but found {})",
|
||||
required.bytes(), has.bytes()), self.path),
|
||||
InterpError::ReadBytesAsPointer =>
|
||||
InterpError::Unsupported(ReadBytesAsPointer) =>
|
||||
return validation_failure!(
|
||||
"dangling reference (created from integer)",
|
||||
self.path
|
||||
@ -608,7 +608,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
||||
Err(err) => {
|
||||
// For some errors we might be able to provide extra information
|
||||
match err.kind {
|
||||
InterpError::ReadUndefBytes(offset) => {
|
||||
InterpError::Unsupported(ReadUndefBytes(offset)) => {
|
||||
// Some byte was undefined, determine which
|
||||
// element that byte belongs to so we can
|
||||
// provide an index.
|
||||
|
@ -257,86 +257,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
Err(error) => {
|
||||
let diagnostic = error_to_const_error(&self.ecx, error);
|
||||
use rustc::mir::interpret::InterpError::*;
|
||||
use rustc::mir::interpret::UnsupportedInfo::*;
|
||||
match diagnostic.error {
|
||||
// don't report these, they make no sense in a const prop context
|
||||
| MachineError(_)
|
||||
| Exit(_)
|
||||
// at runtime these transformations might make sense
|
||||
// FIXME: figure out the rules and start linting
|
||||
| FunctionAbiMismatch(..)
|
||||
| FunctionArgMismatch(..)
|
||||
| FunctionRetMismatch(..)
|
||||
| FunctionArgCountMismatch
|
||||
// fine at runtime, might be a register address or sth
|
||||
| ReadBytesAsPointer
|
||||
// fine at runtime
|
||||
| ReadForeignStatic
|
||||
| Unimplemented(_)
|
||||
// don't report const evaluator limits
|
||||
| StackFrameLimitReached
|
||||
| NoMirFor(..)
|
||||
| InlineAsm
|
||||
=> {},
|
||||
Exit(_) => {},
|
||||
|
||||
| InvalidMemoryAccess
|
||||
| DanglingPointerDeref
|
||||
| DoubleFree
|
||||
| InvalidFunctionPointer
|
||||
| InvalidBool
|
||||
| InvalidDiscriminant(..)
|
||||
| PointerOutOfBounds { .. }
|
||||
| InvalidNullPointerUsage
|
||||
| ValidationFailure(..)
|
||||
| InvalidPointerMath
|
||||
| ReadUndefBytes(_)
|
||||
| DeadLocal
|
||||
| InvalidBoolOp(_)
|
||||
| DerefFunctionPointer
|
||||
| ExecuteMemory
|
||||
| Intrinsic(..)
|
||||
| InvalidChar(..)
|
||||
| AbiViolation(_)
|
||||
| AlignmentCheckFailed{..}
|
||||
| CalledClosureAsFunction
|
||||
| VtableForArgumentlessMethod
|
||||
| ModifiedConstantMemory
|
||||
| ModifiedStatic
|
||||
| AssumptionNotHeld
|
||||
// FIXME: should probably be removed and turned into a bug! call
|
||||
| TypeNotPrimitive(_)
|
||||
| ReallocatedWrongMemoryKind(_, _)
|
||||
| DeallocatedWrongMemoryKind(_, _)
|
||||
| ReallocateNonBasePtr
|
||||
| DeallocateNonBasePtr
|
||||
| IncorrectAllocationInformation(..)
|
||||
| UnterminatedCString(_)
|
||||
| HeapAllocZeroBytes
|
||||
| HeapAllocNonPowerOfTwoAlignment(_)
|
||||
| Unreachable
|
||||
| ReadFromReturnPointer
|
||||
| ReferencedConstant
|
||||
| InfiniteLoop
|
||||
=> {
|
||||
// FIXME: report UB here
|
||||
},
|
||||
|
||||
| OutOfTls
|
||||
| TlsOutOfBounds
|
||||
| PathNotFound(_)
|
||||
| Unsupported(OutOfTls)
|
||||
| Unsupported(TlsOutOfBounds)
|
||||
| Unsupported(PathNotFound(_))
|
||||
=> bug!("these should not be in rustc, but in miri's machine errors"),
|
||||
|
||||
| Layout(_)
|
||||
| UnimplementedTraitSelection
|
||||
| TypeckError
|
||||
| TooGeneric
|
||||
// these are just noise
|
||||
=> {},
|
||||
|
||||
// non deterministic
|
||||
| ReadPointerAsBytes
|
||||
// FIXME: implement
|
||||
=> {},
|
||||
|
||||
| Unsupported(_) => {},
|
||||
| UndefinedBehaviour(_) => {},
|
||||
| InvalidProgram(_) => {},
|
||||
| ResourceExhaustion(_) => {},
|
||||
|
||||
| Panic(_)
|
||||
=> {
|
||||
diagnostic.report_as_lint(
|
||||
|
Loading…
Reference in New Issue
Block a user