Skip to content

Commit

Permalink
Auto merge of #114735 - RalfJung:miri, r=RalfJung
Browse files Browse the repository at this point in the history
update Miri

r? `@ghost`
  • Loading branch information
bors committed Aug 11, 2023
2 parents b03864d + a45f181 commit a6f8aa5
Show file tree
Hide file tree
Showing 16 changed files with 1,795 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/tools/miri/miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl Command {
// the merge has confused the heck out of josh in the past.
// We pass `--no-verify` to avoid running git hooks like `./miri fmt` that could in turn
// trigger auto-actions.
sh.write_file("rust-version", &commit)?;
sh.write_file("rust-version", format!("{commit}\n"))?;
const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc";
cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}")
.run()
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fca59ab5f0e7df7d816bed77a32abc0045ebe80b
9fa6bdd764a1f7bdf69eccceeace6d13f38cb2e1
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
// interleaving, but wether UB happens can depend on whether a write occurs in the
// future...
let is_write = new_perm.initial_state.is_active()
|| (new_perm.initial_state.is_resrved() && new_perm.protector.is_some());
|| (new_perm.initial_state.is_reserved() && new_perm.protector.is_some());
if is_write {
// Need to get mutable access to alloc_extra.
// (Cannot always do this as we can do read-only reborrowing on read-only allocations.)
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl Permission {
matches!(self.inner, Active)
}

pub fn is_resrved(self) -> bool {
pub fn is_reserved(self) -> bool {
matches!(self.inner, Reserved { .. })
}

Expand Down
23 changes: 6 additions & 17 deletions src/tools/miri/src/concurrency/range_object_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,30 +42,19 @@ impl<T> RangeObjectMap<T> {
/// in an existing allocation, then returns Err containing the position
/// where such allocation should be inserted
fn find_offset(&self, offset: Size) -> Result<Position, Position> {
// We do a binary search.
let mut left = 0usize; // inclusive
let mut right = self.v.len(); // exclusive
loop {
if left == right {
// No element contains the given offset. But the
// position is where such element should be placed at.
return Err(left);
}
let candidate = left.checked_add(right).unwrap() / 2;
let elem = &self.v[candidate];
self.v.binary_search_by(|elem| -> std::cmp::Ordering {
if offset < elem.range.start {
// We are too far right (offset is further left).
debug_assert!(candidate < right); // we are making progress
right = candidate;
// (`Greater` means that `elem` is greater than the desired target.)
std::cmp::Ordering::Greater
} else if offset >= elem.range.end() {
// We are too far left (offset is further right).
debug_assert!(candidate >= left); // we are making progress
left = candidate + 1;
std::cmp::Ordering::Less
} else {
// This is it!
return Ok(candidate);
std::cmp::Ordering::Equal
}
}
})
}

/// Determines whether a given access on `range` overlaps with
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
// Third argument (`argv`): created from `config.args`.
let argv = {
// Put each argument in memory, collect pointers.
let mut argvs = Vec::<Immediate<Provenance>>::new();
let mut argvs = Vec::<Immediate<Provenance>>::with_capacity(config.args.len());
for arg in config.args.iter() {
// Make space for `0` terminator.
let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap();
Expand Down
19 changes: 0 additions & 19 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub mod convert;

use std::any::Any;
use std::cmp;
use std::iter;
use std::num::NonZeroUsize;
Expand All @@ -25,24 +24,6 @@ use rand::RngCore;

use crate::*;

/// A trait to work around not having trait object upcasting:
/// Add `AsAny` as supertrait and your trait objects can be turned into `&dyn Any` on which you can
/// then call `downcast`.
pub trait AsAny: Any {
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T: Any> AsAny for T {
#[inline(always)]
fn as_any(&self) -> &dyn Any {
self
}
#[inline(always)]
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}

// This mapping should match `decode_error_kind` in
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unix/mod.rs>.
const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
Expand Down
3 changes: 3 additions & 0 deletions src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(rustc_private)]
#![feature(float_gamma)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
Expand All @@ -10,6 +11,7 @@
#![feature(round_ties_even)]
#![feature(os_str_bytes)]
#![feature(lint_reasons)]
#![feature(trait_upcasting)]
// Configure clippy and other lints
#![allow(
clippy::collapsible_else_if,
Expand All @@ -19,6 +21,7 @@
clippy::enum_variant_names,
clippy::field_reassign_with_default,
clippy::manual_map,
clippy::neg_cmp_op_on_partial_ord,
clippy::new_without_default,
clippy::single_match,
clippy::useless_format,
Expand Down
57 changes: 57 additions & 0 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
| "atanf"
| "log1pf"
| "expm1f"
| "tgammaf"
=> {
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// FIXME: Using host floats.
Expand All @@ -830,6 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"atanf" => f.atan(),
"log1pf" => f.ln_1p(),
"expm1f" => f.exp_m1(),
"tgammaf" => f.gamma(),
_ => bug!(),
};
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
Expand Down Expand Up @@ -866,6 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
| "atan"
| "log1p"
| "expm1"
| "tgamma"
=> {
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// FIXME: Using host floats.
Expand All @@ -881,6 +884,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
"atan" => f.atan(),
"log1p" => f.ln_1p(),
"expm1" => f.exp_m1(),
"tgamma" => f.gamma(),
_ => bug!(),
};
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
Expand Down Expand Up @@ -917,6 +921,53 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let res = x.scalbn(exp);
this.write_scalar(Scalar::from_f64(res), dest)?;
}
"lgammaf_r" => {
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// FIXME: Using host floats.
let x = f32::from_bits(this.read_scalar(x)?.to_u32()?);
let signp = this.deref_pointer(signp)?;

let (res, sign) = x.ln_gamma();
this.write_int(sign, &signp)?;
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
}
"lgamma_r" => {
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
// FIXME: Using host floats.
let x = f64::from_bits(this.read_scalar(x)?.to_u64()?);
let signp = this.deref_pointer(signp)?;

let (res, sign) = x.ln_gamma();
this.write_int(sign, &signp)?;
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
}

"llvm.prefetch" => {
let [p, rw, loc, ty] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

let _ = this.read_pointer(p)?;
let rw = this.read_scalar(rw)?.to_i32()?;
let loc = this.read_scalar(loc)?.to_i32()?;
let ty = this.read_scalar(ty)?.to_i32()?;

if ty == 1 {
// Data cache prefetch.
// Notably, we do not have to check the pointer, this operation is never UB!

if !matches!(rw, 0 | 1) {
throw_unsup_format!("invalid `rw` value passed to `llvm.prefetch`: {}", rw);
}
if !matches!(loc, 0..=3) {
throw_unsup_format!(
"invalid `loc` value passed to `llvm.prefetch`: {}",
loc
);
}
} else {
throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty);
}
}

// Architecture-specific shims
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
Expand Down Expand Up @@ -970,6 +1021,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}

name if name.starts_with("llvm.x86.sse.") => {
return shims::x86::sse::EvalContextExt::emulate_x86_sse_intrinsic(
this, link_name, abi, args, dest,
);
}

// Platform-specific shims
_ =>
return match this.tcx.sess.target.os.as_ref() {
Expand Down
1 change: 1 addition & 0 deletions src/tools/miri/src/shims/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod foreign_items;
pub mod intrinsics;
pub mod unix;
pub mod windows;
mod x86;

pub mod dlsym;
pub mod env;
Expand Down
26 changes: 19 additions & 7 deletions src/tools/miri/src/shims/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::any::Any;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::convert::TryInto;
Expand All @@ -24,7 +25,7 @@ pub struct FileHandle {
writable: bool,
}

pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny {
pub trait FileDescriptor: std::fmt::Debug + Any {
fn name(&self) -> &'static str;

fn read<'tcx>(
Expand Down Expand Up @@ -72,6 +73,18 @@ pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny {
}
}

impl dyn FileDescriptor {
#[inline(always)]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
(self as &dyn Any).downcast_ref()
}

#[inline(always)]
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
(self as &mut dyn Any).downcast_mut()
}
}

impl FileDescriptor for FileHandle {
fn name(&self) -> &'static str {
"FILE"
Expand Down Expand Up @@ -689,7 +702,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
// FIXME: Support fullfsync for all FDs
let FileHandle { file, writable } =
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
err_unsup_format!(
"`F_FULLFSYNC` is only supported on file-backed file descriptors"
)
Expand Down Expand Up @@ -1522,7 +1535,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
if let Some(file_descriptor) = this.machine.file_handler.handles.get_mut(&fd) {
// FIXME: Support ftruncate64 for all FDs
let FileHandle { file, writable } =
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
err_unsup_format!(
"`ftruncate64` is only supported on file-backed file descriptors"
)
Expand Down Expand Up @@ -1568,7 +1581,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
// FIXME: Support fsync for all FDs
let FileHandle { file, writable } =
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
err_unsup_format!("`fsync` is only supported on file-backed file descriptors")
})?;
let io_result = maybe_sync_file(file, *writable, File::sync_all);
Expand All @@ -1593,7 +1606,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
// FIXME: Support fdatasync for all FDs
let FileHandle { file, writable } =
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
err_unsup_format!(
"`fdatasync` is only supported on file-backed file descriptors"
)
Expand Down Expand Up @@ -1643,7 +1656,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
// FIXME: Support sync_data_range for all FDs
let FileHandle { file, writable } =
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
err_unsup_format!(
"`sync_data_range` is only supported on file-backed file descriptors"
)
Expand Down Expand Up @@ -1953,7 +1966,6 @@ impl FileMetadata {
let file = match option {
Some(file_descriptor) =>
&file_descriptor
.as_any()
.downcast_ref::<FileHandle>()
.ok_or_else(|| {
err_unsup_format!(
Expand Down
7 changes: 2 additions & 5 deletions src/tools/miri/src/shims/unix/linux/fd.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::cell::Cell;

use rustc_middle::ty::ScalarInt;

use crate::*;
Expand All @@ -7,8 +9,6 @@ use socketpair::SocketPair;

use shims::unix::fs::EvalContextExt as _;

use std::cell::Cell;

pub mod epoll;
pub mod event;
pub mod socketpair;
Expand Down Expand Up @@ -81,7 +81,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let epfd = epfd
.as_any_mut()
.downcast_mut::<Epoll>()
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?;

Expand All @@ -93,7 +92,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} else if op == epoll_ctl_del {
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let epfd = epfd
.as_any_mut()
.downcast_mut::<Epoll>()
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_ctl`"))?;

Expand Down Expand Up @@ -154,7 +152,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {

if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
let _epfd = epfd
.as_any_mut()
.downcast_mut::<Epoll>()
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?;

Expand Down
1 change: 1 addition & 0 deletions src/tools/miri/src/shims/x86/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub(super) mod sse;
Loading

0 comments on commit a6f8aa5

Please sign in to comment.