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
13 changes: 5 additions & 8 deletions src/borrow_tracker/stacked_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -826,15 +826,12 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
// FIXME: If we cannot determine the size (because the unsized tail is an `extern type`),
// bail out -- we cannot reasonably figure out which memory range to reborrow.
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/276.
let size = match size {
Some(size) => size,
None => {
static DEDUP: AtomicBool = AtomicBool::new(false);
if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) {
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
}
return interp_ok(place.clone());
let Some(size) = size else {
static DEDUP: AtomicBool = AtomicBool::new(false);
if !DEDUP.swap(true, std::sync::atomic::Ordering::Relaxed) {
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
}
return interp_ok(place.clone());
};

// Compute new borrow.
Expand Down
40 changes: 18 additions & 22 deletions src/borrow_tracker/tree_borrows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,26 +219,18 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
};

trace!("Reborrow of size {:?}", ptr_size);
let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr(), 0) {
Ok(data) => {
// Unlike SB, we *do* a proper retag for size 0 if can identify the allocation.
// After all, the pointer may be lazily initialized outside this initial range.
data
}
Err(_) => {
assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here
// This pointer doesn't come with an AllocId, so there's no
// memory to do retagging in.
let new_prov = place.ptr().provenance;
trace!(
"reborrow of size 0: reusing {:?} (pointee {})",
place.ptr(),
place.layout.ty,
);
log_creation(this, None)?;
// Keep original provenance.
return interp_ok(new_prov);
}
// Unlike SB, we *do* a proper retag for size 0 if can identify the allocation.
// After all, the pointer may be lazily initialized outside this initial range.
let Ok((alloc_id, base_offset, parent_prov)) = this.ptr_try_get_alloc_id(place.ptr(), 0)
else {
assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here
// This pointer doesn't come with an AllocId, so there's no
// memory to do retagging in.
let new_prov = place.ptr().provenance;
trace!("reborrow of size 0: reusing {:?} (pointee {})", place.ptr(), place.layout.ty,);
log_creation(this, None)?;
// Keep original provenance.
return interp_ok(new_prov);
};
let new_prov = Provenance::Concrete { alloc_id, tag: new_tag };

Expand Down Expand Up @@ -609,8 +601,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let this = self.eval_context_mut();
let (tag, alloc_id) = match ptr.provenance {
Some(Provenance::Concrete { tag, alloc_id }) => (tag, alloc_id),
_ => {
eprintln!("Can't give the name {name} to Wildcard pointer");
Some(Provenance::Wildcard) => {
eprintln!("Can't give the name {name} to wildcard pointer");
return interp_ok(());
}
None => {
eprintln!("Can't give the name {name} to pointer without provenance");
return interp_ok(());
}
};
Expand Down
5 changes: 2 additions & 3 deletions src/concurrency/weak_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,10 @@ impl StoreBufferAlloc {
range: AllocRange,
) -> InterpResult<'tcx, Option<Ref<'_, StoreBuffer>>> {
let access_type = self.store_buffers.borrow().access_type(range);
let pos = match access_type {
AccessType::PerfectlyOverlapping(pos) => pos,
let AccessType::PerfectlyOverlapping(pos) = access_type else {
// If there is nothing here yet, that means there wasn't an atomic write yet so
// we can't return anything outdated.
_ => return interp_ok(None),
return interp_ok(None);
};
let store_buffer = Ref::map(self.store_buffers.borrow(), |buffer| &buffer[pos]);
interp_ok(Some(store_buffer))
Expand Down
4 changes: 1 addition & 3 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,7 @@ where
{
// Parse argv[0]. Slashes aren't escaped. Literal double quotes are not allowed.
let mut cmd = {
let arg0 = if let Some(arg0) = args.next() {
arg0
} else {
let Some(arg0) = args.next() else {
return vec![0];
};
let arg0 = arg0.as_ref();
Expand Down
7 changes: 6 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@
rustc::potential_query_instability,
rustc::untranslatable_diagnostic,
)]
#![warn(rust_2018_idioms, unqualified_local_imports, clippy::as_conversions)]
#![warn(
rust_2018_idioms,
unqualified_local_imports,
clippy::as_conversions,
clippy::manual_let_else
)]
// Needed for rustdoc from bootstrap (with `-Znormalize-docs`).
#![recursion_limit = "256"]

Expand Down
11 changes: 4 additions & 7 deletions src/shims/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(ptr, 0)?;

// This has to be an actual global fn ptr, not a dlsym function.
let fn_instance = if let Some(GlobalAlloc::Function { instance, .. }) =
this.tcx.try_get_global_alloc(alloc_id)
{
instance
} else {
let Some(GlobalAlloc::Function { instance, .. }) = this.tcx.try_get_global_alloc(alloc_id)
else {
throw_ub_format!("expected static function pointer, found {:?}", ptr);
};

let lo =
this.tcx.sess.source_map().lookup_char_pos(BytePos(offset.bytes().try_into().unwrap()));

let name = fn_instance.to_string();
let name = instance.to_string();
let filename = lo.file.name.prefer_remapped_unconditionally().to_string();

interp_ok((fn_instance, lo, name, filename))
interp_ok((instance, lo, name, filename))
}

fn handle_miri_resolve_frame(
Expand Down
9 changes: 3 additions & 6 deletions src/shims/native_lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
) -> InterpResult<'tcx, bool> {
let this = self.eval_context_mut();
// Get the pointer to the function in the shared object file if it exists.
let code_ptr = match this.get_func_ptr_explicitly_from_lib(link_name) {
Some(ptr) => ptr,
None => {
// Shared object file does not export this function -- try the shims next.
return interp_ok(false);
}
let Some(code_ptr) = this.get_func_ptr_explicitly_from_lib(link_name) else {
// Shared object file does not export this function -- try the shims next.
return interp_ok(false);
};

// Do we have ptrace?
Expand Down
14 changes: 4 additions & 10 deletions src/shims/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let duration = this.deref_pointer_as(duration, this.libc_ty_layout("timespec"))?;
let _rem = this.read_pointer(rem)?; // Signal handlers are not supported, so rem will never be written to.

let duration = match this.read_timespec(&duration)? {
Some(duration) => duration,
None => {
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
}
let Some(duration) = this.read_timespec(&duration)? else {
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
};

this.block_thread(
Expand Down Expand Up @@ -378,11 +375,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
throw_unsup_format!("clock_nanosleep: only CLOCK_MONOTONIC is supported");
}

let duration = match this.read_timespec(&timespec)? {
Some(duration) => duration,
None => {
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
}
let Some(duration) = this.read_timespec(&timespec)? else {
return this.set_last_error_and_return_i32(LibcError("EINVAL"));
};

let timeout_anchor = if flags == 0 {
Expand Down
21 changes: 5 additions & 16 deletions src/shims/unix/freebsd/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// `uaddr2` points to a `struct _umtx_time`.
let umtx_time_place = this.ptr_to_mplace(uaddr2, umtx_time_layout);

let umtx_time = match this.read_umtx_time(&umtx_time_place)? {
Some(ut) => ut,
None => {
return this
.set_last_error_and_return(LibcError("EINVAL"), dest);
}
let Some(umtx_time) = this.read_umtx_time(&umtx_time_place)? else {
return this.set_last_error_and_return(LibcError("EINVAL"), dest);
};

let anchor = if umtx_time.abs_time {
Expand All @@ -122,12 +118,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

// `uaddr2` points to a `struct timespec`.
let timespec = this.ptr_to_mplace(uaddr2, timespec_layout);
let duration = match this.read_timespec(&timespec)? {
Some(duration) => duration,
None => {
return this
.set_last_error_and_return(LibcError("EINVAL"), dest);
}
let Some(duration) = this.read_timespec(&timespec)? else {
return this.set_last_error_and_return(LibcError("EINVAL"), dest);
};

// FreeBSD does not seem to document which clock is used when the timeout
Expand Down Expand Up @@ -220,10 +212,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

let timespec_place = this.project_field(ut, FieldIdx::from_u32(0))?;
// Inner `timespec` must still be valid.
let duration = match this.read_timespec(&timespec_place)? {
Some(dur) => dur,
None => return interp_ok(None),
};
let Some(duration) = this.read_timespec(&timespec_place)? else { return interp_ok(None) };

let flags_place = this.project_field(ut, FieldIdx::from_u32(1))?;
let flags = this.read_scalar(&flags_place)?.to_u32()?;
Expand Down
7 changes: 2 additions & 5 deletions src/shims/unix/linux_like/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,8 @@ pub fn futex<'tcx>(
let timeout = if ecx.ptr_is_null(timeout.ptr())? {
None
} else {
let duration = match ecx.read_timespec(&timeout)? {
Some(duration) => duration,
None => {
return ecx.set_last_error_and_return(LibcError("EINVAL"), dest);
}
let Some(duration) = ecx.read_timespec(&timeout)? else {
return ecx.set_last_error_and_return(LibcError("EINVAL"), dest);
};
let timeout_clock = if op & futex_realtime == futex_realtime {
ecx.check_no_isolation(
Expand Down
13 changes: 5 additions & 8 deletions src/shims/unix/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -887,15 +887,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let mutex_ref = mutex_get_data(this, mutex_op)?.mutex_ref.clone();

// Extract the timeout.
let duration = match this
let Some(duration) = this
.read_timespec(&this.deref_pointer_as(timeout_op, this.libc_ty_layout("timespec"))?)?
{
Some(duration) => duration,
None => {
let einval = this.eval_libc("EINVAL");
this.write_scalar(einval, dest)?;
return interp_ok(());
}
else {
let einval = this.eval_libc("EINVAL");
this.write_scalar(einval, dest)?;
return interp_ok(());
};

let (clock, anchor) = if macos_relative_np {
Expand Down
21 changes: 4 additions & 17 deletions src/shims/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,11 +321,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.windows_ty_layout("BY_HANDLE_FILE_INFORMATION"),
)?;

let fd_num = if let Handle::File(fd_num) = file {
fd_num
} else {
this.invalid_handle("GetFileInformationByHandle")?
};
let Handle::File(fd_num) = file else { this.invalid_handle("GetFileInformationByHandle")? };

let Some(desc) = this.machine.fds.get(fd_num) else {
this.invalid_handle("GetFileInformationByHandle")?
Expand Down Expand Up @@ -448,10 +444,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
throw_unsup_format!("`NtWriteFile` `Key` parameter is non-null, which is unsupported");
}

let fd = match handle {
Handle::File(fd) => fd,
_ => this.invalid_handle("NtWriteFile")?,
};
let Handle::File(fd) = handle else { this.invalid_handle("NtWriteFile")? };

let Some(desc) = this.machine.fds.get(fd) else { this.invalid_handle("NtWriteFile")? };

Expand Down Expand Up @@ -561,10 +554,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
};
let io_status_info = this.project_field_named(&io_status_block, "Information")?;

let fd = match handle {
Handle::File(fd) => fd,
_ => this.invalid_handle("NtWriteFile")?,
};
let Handle::File(fd) = handle else { this.invalid_handle("NtWriteFile")? };

let Some(desc) = this.machine.fds.get(fd) else { this.invalid_handle("NtReadFile")? };

Expand Down Expand Up @@ -620,10 +610,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let new_fp_ptr = this.read_pointer(new_fp)?;
let move_method = this.read_scalar(move_method)?.to_u32()?;

let fd = match file {
Handle::File(fd) => fd,
_ => this.invalid_handle("SetFilePointerEx")?,
};
let Handle::File(fd) = file else { this.invalid_handle("SetFilePointerEx")? };

let Some(desc) = this.machine.fds.get(fd) else {
throw_unsup_format!("`SetFilePointerEx` is only supported on file backed handles");
Expand Down