Skip to content
/ rust Public
forked from rust-lang/rust

Commit a6f8aa5

Browse files
committed
Auto merge of rust-lang#114735 - RalfJung:miri, r=RalfJung
update Miri r? `@ghost`
2 parents b03864d + a45f181 commit a6f8aa5

File tree

16 files changed

+1795
-55
lines changed

16 files changed

+1795
-55
lines changed

Diff for: src/tools/miri/miri-script/src/commands.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ impl Command {
173173
// the merge has confused the heck out of josh in the past.
174174
// We pass `--no-verify` to avoid running git hooks like `./miri fmt` that could in turn
175175
// trigger auto-actions.
176-
sh.write_file("rust-version", &commit)?;
176+
sh.write_file("rust-version", format!("{commit}\n"))?;
177177
const PREPARING_COMMIT_MESSAGE: &str = "Preparing for merge from rustc";
178178
cmd!(sh, "git commit rust-version --no-verify -m {PREPARING_COMMIT_MESSAGE}")
179179
.run()

Diff for: src/tools/miri/rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fca59ab5f0e7df7d816bed77a32abc0045ebe80b
1+
9fa6bdd764a1f7bdf69eccceeace6d13f38cb2e1

Diff for: src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
283283
// interleaving, but wether UB happens can depend on whether a write occurs in the
284284
// future...
285285
let is_write = new_perm.initial_state.is_active()
286-
|| (new_perm.initial_state.is_resrved() && new_perm.protector.is_some());
286+
|| (new_perm.initial_state.is_reserved() && new_perm.protector.is_some());
287287
if is_write {
288288
// Need to get mutable access to alloc_extra.
289289
// (Cannot always do this as we can do read-only reborrowing on read-only allocations.)

Diff for: src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl Permission {
152152
matches!(self.inner, Active)
153153
}
154154

155-
pub fn is_resrved(self) -> bool {
155+
pub fn is_reserved(self) -> bool {
156156
matches!(self.inner, Reserved { .. })
157157
}
158158

Diff for: src/tools/miri/src/concurrency/range_object_map.rs

+6-17
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,19 @@ impl<T> RangeObjectMap<T> {
4242
/// in an existing allocation, then returns Err containing the position
4343
/// where such allocation should be inserted
4444
fn find_offset(&self, offset: Size) -> Result<Position, Position> {
45-
// We do a binary search.
46-
let mut left = 0usize; // inclusive
47-
let mut right = self.v.len(); // exclusive
48-
loop {
49-
if left == right {
50-
// No element contains the given offset. But the
51-
// position is where such element should be placed at.
52-
return Err(left);
53-
}
54-
let candidate = left.checked_add(right).unwrap() / 2;
55-
let elem = &self.v[candidate];
45+
self.v.binary_search_by(|elem| -> std::cmp::Ordering {
5646
if offset < elem.range.start {
5747
// We are too far right (offset is further left).
58-
debug_assert!(candidate < right); // we are making progress
59-
right = candidate;
48+
// (`Greater` means that `elem` is greater than the desired target.)
49+
std::cmp::Ordering::Greater
6050
} else if offset >= elem.range.end() {
6151
// We are too far left (offset is further right).
62-
debug_assert!(candidate >= left); // we are making progress
63-
left = candidate + 1;
52+
std::cmp::Ordering::Less
6453
} else {
6554
// This is it!
66-
return Ok(candidate);
55+
std::cmp::Ordering::Equal
6756
}
68-
}
57+
})
6958
}
7059

7160
/// Determines whether a given access on `range` overlaps with

Diff for: src/tools/miri/src/eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
301301
// Third argument (`argv`): created from `config.args`.
302302
let argv = {
303303
// Put each argument in memory, collect pointers.
304-
let mut argvs = Vec::<Immediate<Provenance>>::new();
304+
let mut argvs = Vec::<Immediate<Provenance>>::with_capacity(config.args.len());
305305
for arg in config.args.iter() {
306306
// Make space for `0` terminator.
307307
let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap();

Diff for: src/tools/miri/src/helpers.rs

-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
pub mod convert;
22

3-
use std::any::Any;
43
use std::cmp;
54
use std::iter;
65
use std::num::NonZeroUsize;
@@ -25,24 +24,6 @@ use rand::RngCore;
2524

2625
use crate::*;
2726

28-
/// A trait to work around not having trait object upcasting:
29-
/// Add `AsAny` as supertrait and your trait objects can be turned into `&dyn Any` on which you can
30-
/// then call `downcast`.
31-
pub trait AsAny: Any {
32-
fn as_any(&self) -> &dyn Any;
33-
fn as_any_mut(&mut self) -> &mut dyn Any;
34-
}
35-
impl<T: Any> AsAny for T {
36-
#[inline(always)]
37-
fn as_any(&self) -> &dyn Any {
38-
self
39-
}
40-
#[inline(always)]
41-
fn as_any_mut(&mut self) -> &mut dyn Any {
42-
self
43-
}
44-
}
45-
4627
// This mapping should match `decode_error_kind` in
4728
// <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/unix/mod.rs>.
4829
const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {

Diff for: src/tools/miri/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(rustc_private)]
2+
#![feature(float_gamma)]
23
#![feature(map_try_insert)]
34
#![feature(never_type)]
45
#![feature(try_blocks)]
@@ -10,6 +11,7 @@
1011
#![feature(round_ties_even)]
1112
#![feature(os_str_bytes)]
1213
#![feature(lint_reasons)]
14+
#![feature(trait_upcasting)]
1315
// Configure clippy and other lints
1416
#![allow(
1517
clippy::collapsible_else_if,
@@ -19,6 +21,7 @@
1921
clippy::enum_variant_names,
2022
clippy::field_reassign_with_default,
2123
clippy::manual_map,
24+
clippy::neg_cmp_op_on_partial_ord,
2225
clippy::new_without_default,
2326
clippy::single_match,
2427
clippy::useless_format,

Diff for: src/tools/miri/src/shims/foreign_items.rs

+57
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
815815
| "atanf"
816816
| "log1pf"
817817
| "expm1f"
818+
| "tgammaf"
818819
=> {
819820
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
820821
// FIXME: Using host floats.
@@ -830,6 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
830831
"atanf" => f.atan(),
831832
"log1pf" => f.ln_1p(),
832833
"expm1f" => f.exp_m1(),
834+
"tgammaf" => f.gamma(),
833835
_ => bug!(),
834836
};
835837
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
@@ -866,6 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
866868
| "atan"
867869
| "log1p"
868870
| "expm1"
871+
| "tgamma"
869872
=> {
870873
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
871874
// FIXME: Using host floats.
@@ -881,6 +884,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
881884
"atan" => f.atan(),
882885
"log1p" => f.ln_1p(),
883886
"expm1" => f.exp_m1(),
887+
"tgamma" => f.gamma(),
884888
_ => bug!(),
885889
};
886890
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
@@ -917,6 +921,53 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
917921
let res = x.scalbn(exp);
918922
this.write_scalar(Scalar::from_f64(res), dest)?;
919923
}
924+
"lgammaf_r" => {
925+
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
926+
// FIXME: Using host floats.
927+
let x = f32::from_bits(this.read_scalar(x)?.to_u32()?);
928+
let signp = this.deref_pointer(signp)?;
929+
930+
let (res, sign) = x.ln_gamma();
931+
this.write_int(sign, &signp)?;
932+
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
933+
}
934+
"lgamma_r" => {
935+
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
936+
// FIXME: Using host floats.
937+
let x = f64::from_bits(this.read_scalar(x)?.to_u64()?);
938+
let signp = this.deref_pointer(signp)?;
939+
940+
let (res, sign) = x.ln_gamma();
941+
this.write_int(sign, &signp)?;
942+
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
943+
}
944+
945+
"llvm.prefetch" => {
946+
let [p, rw, loc, ty] =
947+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
948+
949+
let _ = this.read_pointer(p)?;
950+
let rw = this.read_scalar(rw)?.to_i32()?;
951+
let loc = this.read_scalar(loc)?.to_i32()?;
952+
let ty = this.read_scalar(ty)?.to_i32()?;
953+
954+
if ty == 1 {
955+
// Data cache prefetch.
956+
// Notably, we do not have to check the pointer, this operation is never UB!
957+
958+
if !matches!(rw, 0 | 1) {
959+
throw_unsup_format!("invalid `rw` value passed to `llvm.prefetch`: {}", rw);
960+
}
961+
if !matches!(loc, 0..=3) {
962+
throw_unsup_format!(
963+
"invalid `loc` value passed to `llvm.prefetch`: {}",
964+
loc
965+
);
966+
}
967+
} else {
968+
throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty);
969+
}
970+
}
920971

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

1024+
name if name.starts_with("llvm.x86.sse.") => {
1025+
return shims::x86::sse::EvalContextExt::emulate_x86_sse_intrinsic(
1026+
this, link_name, abi, args, dest,
1027+
);
1028+
}
1029+
9731030
// Platform-specific shims
9741031
_ =>
9751032
return match this.tcx.sess.target.os.as_ref() {

Diff for: src/tools/miri/src/shims/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod foreign_items;
77
pub mod intrinsics;
88
pub mod unix;
99
pub mod windows;
10+
mod x86;
1011

1112
pub mod dlsym;
1213
pub mod env;

Diff for: src/tools/miri/src/shims/unix/fs.rs

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::any::Any;
12
use std::borrow::Cow;
23
use std::collections::BTreeMap;
34
use std::convert::TryInto;
@@ -24,7 +25,7 @@ pub struct FileHandle {
2425
writable: bool,
2526
}
2627

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

3031
fn read<'tcx>(
@@ -72,6 +73,18 @@ pub trait FileDescriptor: std::fmt::Debug + helpers::AsAny {
7273
}
7374
}
7475

76+
impl dyn FileDescriptor {
77+
#[inline(always)]
78+
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
79+
(self as &dyn Any).downcast_ref()
80+
}
81+
82+
#[inline(always)]
83+
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
84+
(self as &mut dyn Any).downcast_mut()
85+
}
86+
}
87+
7588
impl FileDescriptor for FileHandle {
7689
fn name(&self) -> &'static str {
7790
"FILE"
@@ -689,7 +702,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
689702
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
690703
// FIXME: Support fullfsync for all FDs
691704
let FileHandle { file, writable } =
692-
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
705+
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
693706
err_unsup_format!(
694707
"`F_FULLFSYNC` is only supported on file-backed file descriptors"
695708
)
@@ -1522,7 +1535,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
15221535
if let Some(file_descriptor) = this.machine.file_handler.handles.get_mut(&fd) {
15231536
// FIXME: Support ftruncate64 for all FDs
15241537
let FileHandle { file, writable } =
1525-
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
1538+
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
15261539
err_unsup_format!(
15271540
"`ftruncate64` is only supported on file-backed file descriptors"
15281541
)
@@ -1568,7 +1581,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
15681581
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
15691582
// FIXME: Support fsync for all FDs
15701583
let FileHandle { file, writable } =
1571-
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
1584+
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
15721585
err_unsup_format!("`fsync` is only supported on file-backed file descriptors")
15731586
})?;
15741587
let io_result = maybe_sync_file(file, *writable, File::sync_all);
@@ -1593,7 +1606,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
15931606
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
15941607
// FIXME: Support fdatasync for all FDs
15951608
let FileHandle { file, writable } =
1596-
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
1609+
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
15971610
err_unsup_format!(
15981611
"`fdatasync` is only supported on file-backed file descriptors"
15991612
)
@@ -1643,7 +1656,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
16431656
if let Some(file_descriptor) = this.machine.file_handler.handles.get(&fd) {
16441657
// FIXME: Support sync_data_range for all FDs
16451658
let FileHandle { file, writable } =
1646-
file_descriptor.as_any().downcast_ref::<FileHandle>().ok_or_else(|| {
1659+
file_descriptor.downcast_ref::<FileHandle>().ok_or_else(|| {
16471660
err_unsup_format!(
16481661
"`sync_data_range` is only supported on file-backed file descriptors"
16491662
)
@@ -1953,7 +1966,6 @@ impl FileMetadata {
19531966
let file = match option {
19541967
Some(file_descriptor) =>
19551968
&file_descriptor
1956-
.as_any()
19571969
.downcast_ref::<FileHandle>()
19581970
.ok_or_else(|| {
19591971
err_unsup_format!(

Diff for: src/tools/miri/src/shims/unix/linux/fd.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::cell::Cell;
2+
13
use rustc_middle::ty::ScalarInt;
24

35
use crate::*;
@@ -7,8 +9,6 @@ use socketpair::SocketPair;
79

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

10-
use std::cell::Cell;
11-
1212
pub mod epoll;
1313
pub mod event;
1414
pub mod socketpair;
@@ -81,7 +81,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8181

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

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

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

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

Diff for: src/tools/miri/src/shims/x86/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub(super) mod sse;

0 commit comments

Comments
 (0)