Skip to content
Merged
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
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8b94e9e9188b65df38a5f1ae723617dc2dfb3155
d7270712cb446aad0817040bbca73a8d024f67b0
6 changes: 3 additions & 3 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
let main_mir = ecx.load_mir(main_instance.def)?;

if !main_mir.return_ty().is_unit() || main_mir.arg_count != 0 {
return err!(Unimplemented(
throw_unsup!(Unimplemented(
"miri does not support main functions without `fn()` type signatures"
.to_owned(),
));
Expand All @@ -60,7 +60,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
let start_mir = ecx.load_mir(start_instance.def)?;

if start_mir.arg_count != 3 {
return err!(AbiViolation(format!(
throw_unsup!(AbiViolation(format!(
"'start' lang item should have three arguments, but has {}",
start_mir.arg_count
)));
Expand Down Expand Up @@ -200,7 +200,7 @@ pub fn eval_main<'tcx>(
// Special treatment for some error kinds
let msg = match e.kind {
InterpError::Exit(code) => std::process::exit(code),
InterpError::NoMirFor(..) =>
err_unsup!(NoMirFor(..)) =>
format!("{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.", e),
_ => e.to_string()
};
Expand Down
2 changes: 1 addition & 1 deletion src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
})
.ok_or_else(|| {
let path = path.iter().map(|&s| s.to_owned()).collect();
InterpError::PathNotFound(path).into()
err_unsup!(PathNotFound(path)).into()
})
}

Expand Down
14 changes: 7 additions & 7 deletions src/intptrcast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ impl<'mir, 'tcx> GlobalState {
memory: &Memory<'mir, 'tcx, Evaluator<'tcx>>,
) -> InterpResult<'tcx, Pointer<Tag>> {
if int == 0 {
return err!(InvalidNullPointerUsage);
throw_unsup!(InvalidNullPointerUsage);
}

let global_state = memory.extra.intptrcast.borrow();

match global_state.int_to_ptr_map.binary_search_by_key(&int, |(addr, _)| *addr) {
Ok(match global_state.int_to_ptr_map.binary_search_by_key(&int, |(addr, _)| *addr) {
Ok(pos) => {
let (_, alloc_id) = global_state.int_to_ptr_map[pos];
// `int` is equal to the starting address for an allocation, the offset should be
// zero. The pointer is untagged because it was created from a cast
Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged))
Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged)
},
Err(0) => err!(DanglingPointerDeref),
Err(0) => throw_unsup!(DanglingPointerDeref),
Err(pos) => {
// This is the largest of the adresses smaller than `int`,
// i.e. the greatest lower bound (glb)
Expand All @@ -65,12 +65,12 @@ impl<'mir, 'tcx> GlobalState {
// If the offset exceeds the size of the allocation, this access is illegal
if offset <= memory.get(alloc_id)?.bytes.len() as u64 {
// This pointer is untagged because it was created from a cast
Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged))
Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged)
} else {
err!(DanglingPointerDeref)
throw_unsup!(DanglingPointerDeref)
}
}
}
})
}

pub fn ptr_to_int(
Expand Down
2 changes: 1 addition & 1 deletion src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
let data = vec![0; size.bytes() as usize];
Allocation::from_bytes(&data, tcx.data_layout.pointer_align.abi)
}
_ => return err!(Unimplemented(
_ => throw_unsup!(Unimplemented(
format!("can't access foreign static: {}", link_name),
)),
};
Expand Down
29 changes: 14 additions & 15 deletions src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
let right = right.to_scalar()?;
debug_assert!(left.is_ptr() || right.is_ptr() || bin_op == Offset);

match bin_op {
Ok(match bin_op {
Offset => {
let pointee_ty = left_layout.ty
.builtin_deref(true)
Expand All @@ -105,7 +105,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
pointee_ty,
right.to_isize(self)?,
)?;
Ok((ptr, false))
(ptr, false)
}
// These need both to be pointer, and fail if they are not in the same location
Lt | Le | Gt | Ge | Sub if left.is_ptr() && right.is_ptr() => {
Expand All @@ -130,10 +130,10 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
}
_ => bug!("We already established it has to be one of these operators."),
};
Ok((Scalar::from_bool(res), false))
(Scalar::from_bool(res), false)
} else {
// Both are pointers, but from different allocations.
err!(InvalidPointerMath)
throw_unsup!(InvalidPointerMath)
}
}
Gt | Ge if left.is_ptr() && right.is_bits() => {
Expand All @@ -151,10 +151,10 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
};
if result {
// Definitely true!
Ok((Scalar::from_bool(true), false))
(Scalar::from_bool(true), false)
} else {
// Sorry, can't tell.
err!(InvalidPointerMath)
throw_unsup!(InvalidPointerMath)
}
}
// These work if the left operand is a pointer, and the right an integer
Expand All @@ -165,7 +165,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
left.to_ptr().expect("we checked is_ptr"),
right.to_bits(self.memory().pointer_size()).expect("we checked is_bits"),
right_layout.abi.is_signed(),
)
)?
}
// Commutative operators also work if the integer is on the left
Add | BitAnd if left.is_bits() && right.is_ptr() => {
Expand All @@ -175,11 +175,11 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
right.to_ptr().expect("we checked is_ptr"),
left.to_bits(self.memory().pointer_size()).expect("we checked is_bits"),
left_layout.abi.is_signed(),
)
)?
}
// Nothing else works
_ => err!(InvalidPointerMath),
}
_ => throw_unsup!(InvalidPointerMath),
})
}

fn ptr_eq(
Expand Down Expand Up @@ -248,7 +248,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
let v = Scalar::from_uint((left.offset.bytes() as u128) & right, ptr_size);
(v, false)
} else {
return err!(ReadPointerAsBytes);
throw_unsup!(ReadPointerAsBytes);
}
}

Expand All @@ -271,7 +271,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
false,
)
} else {
return err!(ReadPointerAsBytes);
throw_unsup!(ReadPointerAsBytes);
}
}

Expand All @@ -283,7 +283,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
right,
if signed { "signed" } else { "unsigned" }
);
return err!(Unimplemented(msg));
throw_unsup!(Unimplemented(msg));
}
})
}
Expand All @@ -298,12 +298,11 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
pointee_ty: Ty<'tcx>,
offset: i64,
) -> InterpResult<'tcx, Scalar<Tag>> {
use rustc::mir::interpret::InterpError::Panic;
// FIXME: assuming here that type size is less than `i64::max_value()`.
let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
let offset = offset
.checked_mul(pointee_size)
.ok_or_else(|| Panic(PanicMessage::Overflow(mir::BinOp::Mul)))?;
.ok_or_else(|| err_panic!(Overflow(mir::BinOp::Mul)))?;
// Now let's see what kind of pointer this is.
let ptr = if offset == 0 {
match ptr {
Expand Down
2 changes: 1 addition & 1 deletion src/shims/dlsym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Dlsym {
"getentropy" => Some(GetEntropy),
"__pthread_get_minstack" => None,
_ =>
return err!(Unimplemented(format!(
throw_unsup!(Unimplemented(format!(
"Unsupported dlsym: {}", name
))),
})
Expand Down
49 changes: 25 additions & 24 deletions src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
use rustc::mir::interpret::InterpError::Panic;
let this = self.eval_context_mut();
let attrs = this.tcx.get_attrs(def_id);
let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) {
Expand All @@ -142,15 +141,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// First: functions that diverge.
match link_name {
"__rust_start_panic" | "panic_impl" => {
return err!(MachineError("the evaluated program panicked".to_string()));
throw_unsup!(MachineError("the evaluated program panicked".to_string()));
}
"exit" | "ExitProcess" => {
// it's really u32 for ExitProcess, but we have to put it into the `Exit` error variant anyway
let code = this.read_scalar(args[0])?.to_i32()?;
return err!(Exit(code));
return Err(InterpError::Exit(code).into());
}
_ => if dest.is_none() {
return err!(Unimplemented(
throw_unsup!(Unimplemented(
format!("can't call diverging foreign function: {}", link_name),
));
}
Expand All @@ -168,7 +167,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"calloc" => {
let items = this.read_scalar(args[0])?.to_usize(this)?;
let len = this.read_scalar(args[1])?.to_usize(this)?;
let size = items.checked_mul(len).ok_or_else(|| Panic(PanicMessage::Overflow(mir::BinOp::Mul)))?;
let size = items.checked_mul(len).ok_or_else(|| err_panic!(Overflow(mir::BinOp::Mul)))?;
let res = this.malloc(size, /*zero_init:*/ true, MiriMemoryKind::C);
this.write_scalar(res, dest)?;
}
Expand All @@ -178,13 +177,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let size = this.read_scalar(args[2])?.to_usize(this)?;
// Align must be power of 2, and also at least ptr-sized (POSIX rules).
if !align.is_power_of_two() {
return err!(HeapAllocNonPowerOfTwoAlignment(align));
throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));
}
/*
FIXME: This check is disabled because rustc violates it.
See <https://github.com/rust-lang/rust/issues/62251>.
if align < this.pointer_size().bytes() {
return err!(MachineError(format!(
throw_unsup!(MachineError(format!(
"posix_memalign: alignment must be at least the size of a pointer, but is {}",
align,
)));
Expand Down Expand Up @@ -217,10 +216,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let size = this.read_scalar(args[0])?.to_usize(this)?;
let align = this.read_scalar(args[1])?.to_usize(this)?;
if size == 0 {
return err!(HeapAllocZeroBytes);
throw_unsup!(HeapAllocZeroBytes);
}
if !align.is_power_of_two() {
return err!(HeapAllocNonPowerOfTwoAlignment(align));
throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));
}
let ptr = this.memory_mut()
.allocate(
Expand All @@ -234,10 +233,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let size = this.read_scalar(args[0])?.to_usize(this)?;
let align = this.read_scalar(args[1])?.to_usize(this)?;
if size == 0 {
return err!(HeapAllocZeroBytes);
throw_unsup!(HeapAllocZeroBytes);
}
if !align.is_power_of_two() {
return err!(HeapAllocNonPowerOfTwoAlignment(align));
throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));
}
let ptr = this.memory_mut()
.allocate(
Expand All @@ -256,10 +255,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let old_size = this.read_scalar(args[1])?.to_usize(this)?;
let align = this.read_scalar(args[2])?.to_usize(this)?;
if old_size == 0 {
return err!(HeapAllocZeroBytes);
throw_unsup!(HeapAllocZeroBytes);
}
if !align.is_power_of_two() {
return err!(HeapAllocNonPowerOfTwoAlignment(align));
throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));
}
let ptr = this.force_ptr(ptr)?;
this.memory_mut().deallocate(
Expand All @@ -274,10 +273,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let align = this.read_scalar(args[2])?.to_usize(this)?;
let new_size = this.read_scalar(args[3])?.to_usize(this)?;
if old_size == 0 || new_size == 0 {
return err!(HeapAllocZeroBytes);
throw_unsup!(HeapAllocZeroBytes);
}
if !align.is_power_of_two() {
return err!(HeapAllocNonPowerOfTwoAlignment(align));
throw_unsup!(HeapAllocNonPowerOfTwoAlignment(align));
}
let align = Align::from_bytes(align).unwrap();
let new_ptr = this.memory_mut().reallocate(
Expand Down Expand Up @@ -310,7 +309,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
}
id => {
return err!(Unimplemented(
throw_unsup!(Unimplemented(
format!("miri does not support syscall ID {}", id),
))
}
Expand Down Expand Up @@ -361,10 +360,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let mut args = this.frame().body.args_iter();

let arg_local = args.next().ok_or_else(||
InterpError::AbiViolation(
err_unsup!(AbiViolation(
"Argument to __rust_maybe_catch_panic does not take enough arguments."
.to_owned(),
),
)),
)?;
let arg_dest = this.local_place(arg_local)?;
this.write_scalar(data, arg_dest)?;
Expand Down Expand Up @@ -633,7 +632,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
if let Some(result) = result {
this.write_scalar(result, dest)?;
} else {
return err!(Unimplemented(
throw_unsup!(Unimplemented(
format!("Unimplemented sysconf name: {}", name),
));
}
Expand Down Expand Up @@ -662,14 +661,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// This is `libc::pthread_key_t`.
let key_type = args[0].layout.ty
.builtin_deref(true)
.ok_or_else(|| InterpError::AbiViolation("wrong signature used for `pthread_key_create`: first argument must be a raw pointer.".to_owned()))?
.ok_or_else(|| err_unsup!(
AbiViolation("wrong signature used for `pthread_key_create`: first argument must be a raw pointer.".to_owned())
))?
.ty;
let key_layout = this.layout_of(key_type)?;

// Create key and write it into the memory where `key_ptr` wants it.
let key = this.machine.tls.create_tls_key(dtor) as u128;
if key_layout.size.bits() < 128 && key >= (1u128 << key_layout.size.bits() as u128) {
return err!(OutOfTls);
throw_unsup!(OutOfTls);
}

let key_ptr = this.memory().check_ptr_access(key_ptr, key_layout.size, key_layout.align.abi)?
Expand Down Expand Up @@ -728,7 +729,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

// We don't support threading. (Also for Windows.)
"pthread_create" | "CreateThread" => {
return err!(Unimplemented(format!("Miri does not support threading")));
throw_unsup!(Unimplemented(format!("Miri does not support threading")));
}

// Stub out calls for condvar, mutex and rwlock, to just return `0`.
Expand Down Expand Up @@ -869,7 +870,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// Figure out how large a TLS key actually is. This is `c::DWORD`.
if dest.layout.size.bits() < 128
&& key >= (1u128 << dest.layout.size.bits() as u128) {
return err!(OutOfTls);
throw_unsup!(OutOfTls);
}
this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
}
Expand Down Expand Up @@ -947,7 +948,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

// We can't execute anything else.
_ => {
return err!(Unimplemented(
throw_unsup!(Unimplemented(
format!("can't call foreign function: {}", link_name),
));
}
Expand Down
Loading