-8e917f48382c6afaf50568263b89d35fba5d98e4
+a45743345659c775b01484574af2818c46a2cb03
let main_mir = ecx.load_mir(main_instance.def)?;
if !main_mir.return_ty().is_unit() || main_mir.arg_count != 0 {
- throw_unsup!(Unimplemented(
+ throw_unsup_format!(
"miri does not support main functions without `fn()` type signatures"
- .to_owned(),
- ));
+ );
}
let start_id = tcx.lang_items().start_fn().unwrap();
let start_mir = ecx.load_mir(start_instance.def)?;
if start_mir.arg_count != 3 {
- throw_unsup!(AbiViolation(format!(
+ bug!(
"'start' lang item should have three arguments, but has {}",
start_mir.arg_count
- )));
+ );
}
// Return value (in static memory so that it does not count as leak).
let data = vec![0; size.bytes() as usize];
Allocation::from_bytes(&data, tcx.data_layout.pointer_align.abi)
}
- _ => throw_unsup!(Unimplemented(
- format!("can't access foreign static: {}", link_name),
- )),
+ _ => throw_unsup_format!("can't access foreign static: {}", link_name),
};
Ok(Cow::Owned(alloc))
}
"getentropy" => Some(GetEntropy),
"__pthread_get_minstack" => None,
_ =>
- throw_unsup!(Unimplemented(format!(
- "Unsupported dlsym: {}", name
- ))),
+ throw_unsup_format!("Unsupported dlsym: {}", name),
})
}
}
// First: functions that diverge.
match link_name {
"__rust_start_panic" | "panic_impl" => {
- throw_unsup!(MachineError("the evaluated program panicked".to_string()));
+ throw_unsup_format!("the evaluated program panicked");
}
"exit" | "ExitProcess" => {
// it's really u32 for ExitProcess, but we have to put it into the `Exit` error variant anyway
return Err(InterpError::Exit(code).into());
}
_ => if dest.is_none() {
- throw_unsup!(Unimplemented(
- format!("can't call diverging foreign function: {}", link_name),
- ));
+ throw_unsup_format!("can't call (diverging) foreign function: {}", link_name);
}
}
if !align.is_power_of_two() {
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() {
- throw_unsup!(MachineError(format!(
+ throw_ub_format!(
"posix_memalign: alignment must be at least the size of a pointer, but is {}",
align,
- )));
+ );
}
- */
+
if size == 0 {
this.write_null(ret.into())?;
} else {
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
}
id => {
- throw_unsup!(Unimplemented(
- format!("miri does not support syscall ID {}", id),
- ))
+ throw_unsup_format!("miri does not support syscall ID {}", id)
}
}
}
)?;
let mut args = this.frame().body.args_iter();
- let arg_local = args.next().ok_or_else(||
- err_unsup!(AbiViolation(
- "Argument to __rust_maybe_catch_panic does not take enough arguments."
- .to_owned(),
- )),
- )?;
+ let arg_local = args.next()
+ .expect("Argument to __rust_maybe_catch_panic does not take enough arguments.");
let arg_dest = this.local_place(arg_local)?;
this.write_scalar(data, arg_dest)?;
};
this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?;
}
+ // underscore case for windows
+ "_ldexp" | "ldexp" => {
+ // FIXME: Using host floats.
+ let x = f64::from_bits(this.read_scalar(args[0])?.to_u64()?);
+ let exp = this.read_scalar(args[1])?.to_i32()?;
+ // FIXME: We should use cmath if there are any imprecisions.
+ let n = x * 2.0f64.powi(exp);
+ this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?;
+ }
// Some things needed for `sys::thread` initialization to go through.
"signal" | "sigaction" | "sigaltstack" => {
if let Some(result) = result {
this.write_scalar(result, dest)?;
} else {
- throw_unsup!(Unimplemented(
- format!("Unimplemented sysconf name: {}", name),
- ));
+ throw_unsup_format!("Unimplemented sysconf name: {}", name)
}
}
// This is `libc::pthread_key_t`.
let key_type = args[0].layout.ty
.builtin_deref(true)
- .ok_or_else(|| err_unsup!(
- AbiViolation("wrong signature used for `pthread_key_create`: first argument must be a raw pointer.".to_owned())
- ))?
+ .ok_or_else(|| err_ub!(Ub(format!(
+ "wrong signature used for `pthread_key_create`: first argument must be a raw pointer."
+ ))))?
.ty;
let key_layout = this.layout_of(key_type)?;
// We don't support threading. (Also for Windows.)
"pthread_create" | "CreateThread" => {
- throw_unsup!(Unimplemented(format!("Miri does not support threading")));
+ throw_unsup_format!("Miri does not support threading");
}
// Stub out calls for condvar, mutex and rwlock, to just return `0`.
// We can't execute anything else.
_ => {
- throw_unsup!(Unimplemented(
- format!("can't call foreign function: {}", link_name),
- ));
+ throw_unsup_format!("can't call foreign function: {}", link_name)
}
}
}
return Ok(None);
}
-}
\ No newline at end of file
+}
"atomic_xsub_relaxed" => {
let ptr = this.deref_operand(args[0])?;
if !ptr.layout.ty.is_integral() {
- throw_unsup!(Unimplemented(format!("Atomic arithmetic operations only work on integer types")));
+ bug!("Atomic arithmetic operations only work on integer types");
}
let rhs = this.read_immediate(args[1])?;
let old = this.read_immediate(ptr.into())?;
// Check if `b` is -1, which is the "min_value / -1" case.
let minus1 = Scalar::from_int(-1, dest.layout.size);
return Err(if b.to_scalar().unwrap() == minus1 {
- err_unsup!(Intrinsic(format!("exact_div: result of dividing MIN by -1 cannot be represented")))
+ err_ub!(Ub(format!("exact_div: result of dividing MIN by -1 cannot be represented")))
} else {
- err_unsup!(Intrinsic(format!("exact_div: {:?} cannot be divided by {:?} without remainder", *a, *b)))
+ err_ub!(Ub(format!("exact_div: {:?} cannot be divided by {:?} without remainder", *a, *b)))
}.into());
}
this.binop_ignore_overflow(mir::BinOp::Div, a, b, dest)?;
let ty = substs.type_at(0);
let layout = this.layout_of(ty)?;
if layout.abi.is_uninhabited() {
- throw_unsup!(Intrinsic(format!("Trying to instantiate uninhabited type {}", ty)))
+ throw_ub_format!("Trying to instantiate uninhabited type {}", ty)
}
}
let r = this.read_immediate(args[1])?;
let rval = r.to_scalar()?.to_bits(args[1].layout.size)?;
if rval == 0 {
- throw_unsup!(Intrinsic(format!("Division by 0 in unchecked_div")));
+ throw_ub_format!("Division by 0 in unchecked_div");
}
this.binop_ignore_overflow(
mir::BinOp::Div,
let r = this.read_immediate(args[1])?;
let rval = r.to_scalar()?.to_bits(args[1].layout.size)?;
if rval == 0 {
- throw_unsup!(Intrinsic(format!("Division by 0 in unchecked_rem")));
+ throw_ub_format!("Division by 0 in unchecked_rem");
}
this.binop_ignore_overflow(
mir::BinOp::Rem,
};
let (res, overflowed) = this.binary_op(op, l, r)?;
if overflowed {
- throw_unsup!(Intrinsic(format!("Overflowing arithmetic in {}", intrinsic_name.get())));
+ throw_ub_format!("Overflowing arithmetic in {}", intrinsic_name.get());
}
this.write_scalar(res, dest)?;
}
}
}
- name => throw_unsup!(Unimplemented(format!("unimplemented intrinsic: {}", name))),
+ name => throw_unsup_format!("unimplemented intrinsic: {}", name),
}
Ok(())
StackPopCleanup::None { cleanup: true },
)?;
let arg_local = this.frame().body.args_iter().next().ok_or_else(
- || err_unsup!(AbiViolation("TLS dtor does not take enough arguments.".to_owned())),
+ || err_ub!(Ub(format!("TLS dtor does not take enough arguments."))),
)?;
let dest = this.local_place(arg_local)?;
this.write_scalar(ptr, dest)?;
if let Some(call) = item.protector {
if global.is_active(call) {
if let Some(tag) = tag {
- throw_unsup!(MachineError(format!(
+ throw_ub_format!(
"not granting access to tag {:?} because incompatible item is protected: {:?}",
tag, item
- )));
+ );
} else {
- throw_unsup!(MachineError(format!(
+ throw_ub_format!(
"deallocating while item is protected: {:?}", item
- )));
+ );
}
}
}
// Step 1: Find granting item.
let granting_idx = self.find_granting(access, tag)
- .ok_or_else(|| err_unsup!(MachineError(format!(
+ .ok_or_else(|| err_ub!(Ub(format!(
"no item granting {} to tag {:?} found in borrow stack",
access, tag,
))))?;
) -> InterpResult<'tcx> {
// Step 1: Find granting item.
self.find_granting(AccessKind::Write, tag)
- .ok_or_else(|| err_unsup!(MachineError(format!(
+ .ok_or_else(|| err_ub!(Ub(format!(
"no item granting write access for deallocation to tag {:?} found in borrow stack",
tag,
))))?;
// Now we figure out which item grants our parent (`derived_from`) this kind of access.
// We use that to determine where to put the new item.
let granting_idx = self.find_granting(access, derived_from)
- .ok_or_else(|| err_unsup!(MachineError(format!(
+ .ok_or_else(|| err_ub!(Ub(format!(
"trying to reborrow for {:?}, but parent tag {:?} does not have an appropriate item in the borrow stack", new.perm, derived_from,
))))?;
+++ /dev/null
-#![feature(core_intrinsics)]
-
-pub fn main() {
- let mut z: f64 = 1.0;
- unsafe {
- ::std::intrinsics::atomic_xadd(&mut z, 2.0);
- //~^ ERROR: Atomic arithmetic operations only work on integer types
- }
-}
unsafe {
use crate::rusti::*;
- ctlz_nonzero(0u8); //~ ERROR ctlz_nonzero called on 0
+ ctlz_nonzero(0u8); //~ ERROR `ctlz_nonzero` called on 0
}
}
unsafe {
use crate::rusti::*;
- cttz_nonzero(0u8); //~ ERROR cttz_nonzero called on 0
+ cttz_nonzero(0u8); //~ ERROR `cttz_nonzero` called on 0
}
}
use std::intrinsics::*;
-//error-pattern: Overflowing shift by 64 in unchecked_shr
+//error-pattern: Overflowing shift by 64 in `unchecked_shr`
fn main() {
unsafe {
assert_approx_eq!(1.0f32.tan(), 1.557408f32);
assert_approx_eq!(1.0f64.tan(), 1.557408f64);
+ extern {
+ fn ldexp(x: f64, n: i32) -> f64;
+ }
+ unsafe { assert_approx_eq!(ldexp(0.65f64, 3i32), 5.2f64); }
}