Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 80f2908

Browse files
authoredFeb 26, 2023
Rollup merge of #108500 - RalfJung:miri, r=RalfJung
update Miri r? `@ghost`
2 parents e237c9d + 3f88f4c commit 80f2908

File tree

28 files changed

+274
-55
lines changed

28 files changed

+274
-55
lines changed
 

‎Cargo.lock

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ dependencies = [
444444
"directories",
445445
"rustc-build-sysroot",
446446
"rustc-workspace-hack",
447-
"rustc_tools_util 0.2.1",
447+
"rustc_tools_util",
448448
"rustc_version",
449449
"serde",
450450
"serde_json",
@@ -738,7 +738,7 @@ dependencies = [
738738
"regex",
739739
"rustc-semver",
740740
"rustc-workspace-hack",
741-
"rustc_tools_util 0.3.0",
741+
"rustc_tools_util",
742742
"semver",
743743
"serde",
744744
"syn",
@@ -4727,12 +4727,6 @@ dependencies = [
47274727
"tracing",
47284728
]
47294729

4730-
[[package]]
4731-
name = "rustc_tools_util"
4732-
version = "0.2.1"
4733-
source = "registry+https://github.com/rust-lang/crates.io-index"
4734-
checksum = "598f48ce2a421542b3e64828aa742b687cc1b91d2f96591cfdb7ac5988cd6366"
4735-
47364730
[[package]]
47374731
name = "rustc_tools_util"
47384732
version = "0.3.0"

‎src/tools/miri/CONTRIBUTING.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ josh-proxy --local=$HOME/.cache/josh --remote=https://github.com --no-background
242242

243243
This uses a directory `$HOME/.cache/josh` as a cache, to speed up repeated pulling/pushing.
244244

245+
To make josh push via ssh instead of https, you can add the following to your `.gitconfig`:
246+
247+
```toml
248+
[url "git@github.com:"]
249+
pushInsteadOf = https://github.com/
250+
```
251+
245252
### Importing changes from the rustc repo
246253

247254
Josh needs to be running, as described above.

‎src/tools/miri/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ degree documented below):
213213
- The best-supported target is `x86_64-unknown-linux-gnu`. Miri releases are
214214
blocked on things working with this target. Most other Linux targets should
215215
also work well; we do run the test suite on `i686-unknown-linux-gnu` as a
216-
32bit target and `mips64-unknown-linux-gnuabi64` as a big-endian target.
216+
32bit target and `mips64-unknown-linux-gnuabi64` as a big-endian target, as
217+
well as the ARM targets `aarch64-unknown-linux-gnu` and
218+
`arm-unknown-linux-gnueabi`.
217219
- `x86_64-apple-darwin` should work basically as well as Linux. We also test
218220
`aarch64-apple-darwin`. However, we might ship Miri with a nightly even when
219221
some features on these targets regress.
@@ -590,7 +592,7 @@ extern "Rust" {
590592
/// `out` must point to at least `out_size` many bytes, and the result will be stored there
591593
/// with a null terminator.
592594
/// Returns 0 if the `out` buffer was large enough, and the required size otherwise.
593-
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
595+
fn miri_host_to_target_path(path: *const std::ffi::c_char, out: *mut std::ffi::c_char, out_size: usize) -> usize;
594596
}
595597
```
596598

‎src/tools/miri/cargo-miri/Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb"
193193

194194
[[package]]
195195
name = "rustc_tools_util"
196-
version = "0.2.1"
196+
version = "0.3.0"
197197
source = "registry+https://github.com/rust-lang/crates.io-index"
198-
checksum = "598f48ce2a421542b3e64828aa742b687cc1b91d2f96591cfdb7ac5988cd6366"
198+
checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
199199

200200
[[package]]
201201
name = "rustc_version"

‎src/tools/miri/cargo-miri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ rustc-workspace-hack = "1.0.0"
3030
serde = { version = "*", features = ["derive"] }
3131

3232
[build-dependencies]
33-
rustc_tools_util = "0.2"
33+
rustc_tools_util = "0.3"

‎src/tools/miri/cargo-miri/build.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,5 @@ fn main() {
22
// Don't rebuild miri when nothing changed.
33
println!("cargo:rerun-if-changed=build.rs");
44
// gather version info
5-
println!(
6-
"cargo:rustc-env=GIT_HASH={}",
7-
rustc_tools_util::get_commit_hash().unwrap_or_default()
8-
);
9-
println!(
10-
"cargo:rustc-env=COMMIT_DATE={}",
11-
rustc_tools_util::get_commit_date().unwrap_or_default()
12-
);
5+
rustc_tools_util::setup_version_info!();
136
}

‎src/tools/miri/ci.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ run_tests
104104
case $HOST_TARGET in
105105
x86_64-unknown-linux-gnu)
106106
MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
107+
MIRI_TEST_TARGET=aarch64-unknown-linux-gnu run_tests
107108
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
108109
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
109110
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
@@ -118,6 +119,7 @@ case $HOST_TARGET in
118119
MIRI_TEST_TARGET=x86_64-pc-windows-msvc run_tests
119120
;;
120121
i686-pc-windows-msvc)
122+
MIRI_TEST_TARGET=arm-unknown-linux-gnueabi run_tests
121123
MIRI_TEST_TARGET=x86_64-unknown-linux-gnu run_tests
122124
MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
123125
;;

‎src/tools/miri/rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c54c8cbac882e149e04a9e1f2d146fd548ae30ae
1+
c4e0cd966062ca67daed20775f4e8a60c28e57df

‎src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,7 @@ impl NewPermission {
148148
NewPermission::Uniform {
149149
perm: Permission::Unique,
150150
access: Some(AccessKind::Write),
151-
protector: (kind == RetagKind::FnEntry)
152-
.then_some(ProtectorKind::WeakProtector),
151+
protector: (kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector),
153152
}
154153
} else {
155154
// `!Unpin` boxes do not get `noalias` nor `dereferenceable`.

‎src/tools/miri/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![allow(
1414
clippy::collapsible_else_if,
1515
clippy::collapsible_if,
16+
clippy::if_same_then_else,
1617
clippy::comparison_chain,
1718
clippy::enum_variant_names,
1819
clippy::field_reassign_with_default,
@@ -21,7 +22,7 @@
2122
clippy::single_match,
2223
clippy::useless_format,
2324
clippy::derive_partial_eq_without_eq,
24-
clippy::derive_hash_xor_eq,
25+
clippy::derived_hash_with_manual_eq,
2526
clippy::too_many_arguments,
2627
clippy::type_complexity,
2728
clippy::single_element_loop,

‎src/tools/miri/src/machine.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,8 @@ pub struct MiriMachine<'mir, 'tcx> {
477477

478478
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
479479
pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Self {
480-
let local_crates = helpers::get_local_crates(layout_cx.tcx);
480+
let tcx = layout_cx.tcx;
481+
let local_crates = helpers::get_local_crates(tcx);
481482
let layouts =
482483
PrimitiveLayouts::new(layout_cx).expect("Couldn't get layouts of primitive types");
483484
let profiler = config.measureme_out.as_ref().map(|out| {
@@ -486,10 +487,13 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
486487
let rng = StdRng::seed_from_u64(config.seed.unwrap_or(0));
487488
let borrow_tracker = config.borrow_tracker.map(|bt| bt.instanciate_global_state(config));
488489
let data_race = config.data_race_detector.then(|| data_race::GlobalState::new(config));
490+
// Determinine page size, stack address, and stack size.
491+
// These values are mostly meaningless, but the stack address is also where we start
492+
// allocating physical integer addresses for all allocations.
489493
let page_size = if let Some(page_size) = config.page_size {
490494
page_size
491495
} else {
492-
let target = &layout_cx.tcx.sess.target;
496+
let target = &tcx.sess.target;
493497
match target.arch.as_ref() {
494498
"wasm32" | "wasm64" => 64 * 1024, // https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances
495499
"aarch64" =>
@@ -504,10 +508,12 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
504508
_ => 4 * 1024,
505509
}
506510
};
507-
let stack_addr = page_size * 32;
508-
let stack_size = page_size * 16;
511+
// On 16bit targets, 32 pages is more than the entire address space!
512+
let stack_addr = if tcx.pointer_size().bits() < 32 { page_size } else { page_size * 32 };
513+
let stack_size =
514+
if tcx.pointer_size().bits() < 32 { page_size * 4 } else { page_size * 16 };
509515
MiriMachine {
510-
tcx: layout_cx.tcx,
516+
tcx,
511517
borrow_tracker,
512518
data_race,
513519
intptrcast: RefCell::new(intptrcast::GlobalStateInner::new(config, stack_addr)),
@@ -902,8 +908,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
902908
};
903909
let (shim_size, shim_align, _kind) = ecx.get_alloc_info(alloc_id);
904910
let def_ty = ecx.tcx.type_of(def_id).subst_identity();
905-
let extern_decl_layout =
906-
ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap();
911+
let extern_decl_layout = ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap();
907912
if extern_decl_layout.size != shim_size || extern_decl_layout.align.abi != shim_align {
908913
throw_unsup_format!(
909914
"`extern` static `{name}` from crate `{krate}` has been declared \

‎src/tools/miri/src/shims/foreign_items.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
885885
}
886886
}
887887
}
888+
"llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
889+
let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
890+
let arg = this.read_scalar(arg)?.to_i32()?;
891+
match arg {
892+
// YIELD
893+
1 => {
894+
this.yield_active_thread();
895+
}
896+
_ => {
897+
throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg);
898+
}
899+
}
900+
}
888901

889902
// Platform-specific shims
890903
_ =>

‎src/tools/miri/src/shims/unix/linux/fd.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use socketpair::SocketPair;
77

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

10+
use std::cell::Cell;
11+
1012
pub mod epoll;
1113
pub mod event;
1214
pub mod socketpair;
@@ -101,6 +103,60 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
101103
}
102104
}
103105

106+
/// The `epoll_wait()` system call waits for events on the `Epoll`
107+
/// instance referred to by the file descriptor `epfd`. The buffer
108+
/// pointed to by `events` is used to return information from the ready
109+
/// list about file descriptors in the interest list that have some
110+
/// events available. Up to `maxevents` are returned by `epoll_wait()`.
111+
/// The `maxevents` argument must be greater than zero.
112+
113+
/// The `timeout` argument specifies the number of milliseconds that
114+
/// `epoll_wait()` will block. Time is measured against the
115+
/// CLOCK_MONOTONIC clock.
116+
117+
/// A call to `epoll_wait()` will block until either:
118+
/// • a file descriptor delivers an event;
119+
/// • the call is interrupted by a signal handler; or
120+
/// • the timeout expires.
121+
122+
/// Note that the timeout interval will be rounded up to the system
123+
/// clock granularity, and kernel scheduling delays mean that the
124+
/// blocking interval may overrun by a small amount. Specifying a
125+
/// timeout of -1 causes `epoll_wait()` to block indefinitely, while
126+
/// specifying a timeout equal to zero cause `epoll_wait()` to return
127+
/// immediately, even if no events are available.
128+
///
129+
/// On success, `epoll_wait()` returns the number of file descriptors
130+
/// ready for the requested I/O, or zero if no file descriptor became
131+
/// ready during the requested timeout milliseconds. On failure,
132+
/// `epoll_wait()` returns -1 and errno is set to indicate the error.
133+
///
134+
/// <https://man7.org/linux/man-pages/man2/epoll_wait.2.html>
135+
fn epoll_wait(
136+
&mut self,
137+
epfd: &OpTy<'tcx, Provenance>,
138+
events: &OpTy<'tcx, Provenance>,
139+
maxevents: &OpTy<'tcx, Provenance>,
140+
timeout: &OpTy<'tcx, Provenance>,
141+
) -> InterpResult<'tcx, Scalar<Provenance>> {
142+
let this = self.eval_context_mut();
143+
144+
let epfd = this.read_scalar(epfd)?.to_i32()?;
145+
let _events = this.read_scalar(events)?.to_pointer(this)?;
146+
let _maxevents = this.read_scalar(maxevents)?.to_i32()?;
147+
let _timeout = this.read_scalar(timeout)?.to_i32()?;
148+
149+
let numevents = 0;
150+
if let Some(epfd) = this.machine.file_handler.handles.get_mut(&epfd) {
151+
let _epfd = epfd.as_epoll_handle()?;
152+
153+
// FIXME return number of events ready when scheme for marking events ready exists
154+
Ok(Scalar::from_i32(numevents))
155+
} else {
156+
Ok(Scalar::from_i32(this.handle_not_found()?))
157+
}
158+
}
159+
104160
/// This function creates an `Event` that is used as an event wait/notify mechanism by
105161
/// user-space applications, and by the kernel to notify user-space applications of events.
106162
/// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized
@@ -142,7 +198,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
142198
}
143199

144200
let fh = &mut this.machine.file_handler;
145-
let fd = fh.insert_fd(Box::new(Event { val }));
201+
let fd = fh.insert_fd(Box::new(Event { val: Cell::new(val.into()) }));
146202
Ok(Scalar::from_i32(fd))
147203
}
148204

‎src/tools/miri/src/shims/unix/linux/fd/event.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::shims::unix::fs::FileDescriptor;
22

33
use rustc_const_eval::interpret::InterpResult;
44

5+
use std::cell::Cell;
56
use std::io;
67

78
/// A kind of file descriptor created by `eventfd`.
@@ -13,7 +14,9 @@ use std::io;
1314
/// <https://man.netbsd.org/eventfd.2>
1415
#[derive(Debug)]
1516
pub struct Event {
16-
pub val: u32,
17+
/// The object contains an unsigned 64-bit integer (uint64_t) counter that is maintained by the
18+
/// kernel. This counter is initialized with the value specified in the argument initval.
19+
pub val: Cell<u64>,
1720
}
1821

1922
impl FileDescriptor for Event {
@@ -22,7 +25,7 @@ impl FileDescriptor for Event {
2225
}
2326

2427
fn dup(&mut self) -> io::Result<Box<dyn FileDescriptor>> {
25-
Ok(Box::new(Event { val: self.val }))
28+
Ok(Box::new(Event { val: self.val.clone() }))
2629
}
2730

2831
fn is_tty(&self) -> bool {
@@ -35,4 +38,32 @@ impl FileDescriptor for Event {
3538
) -> InterpResult<'tcx, io::Result<i32>> {
3639
Ok(Ok(0))
3740
}
41+
42+
/// A write call adds the 8-byte integer value supplied in
43+
/// its buffer to the counter. The maximum value that may be
44+
/// stored in the counter is the largest unsigned 64-bit value
45+
/// minus 1 (i.e., 0xfffffffffffffffe). If the addition would
46+
/// cause the counter's value to exceed the maximum, then the
47+
/// write either blocks until a read is performed on the
48+
/// file descriptor, or fails with the error EAGAIN if the
49+
/// file descriptor has been made nonblocking.
50+
51+
/// A write fails with the error EINVAL if the size of the
52+
/// supplied buffer is less than 8 bytes, or if an attempt is
53+
/// made to write the value 0xffffffffffffffff.
54+
///
55+
/// FIXME: use endianness
56+
fn write<'tcx>(
57+
&self,
58+
_communicate_allowed: bool,
59+
bytes: &[u8],
60+
) -> InterpResult<'tcx, io::Result<usize>> {
61+
let v1 = self.val.get();
62+
// FIXME handle blocking when addition results in exceeding the max u64 value
63+
// or fail with EAGAIN if the file descriptor is nonblocking.
64+
let v2 = v1.checked_add(u64::from_be_bytes(bytes.try_into().unwrap())).unwrap();
65+
self.val.set(v2);
66+
assert_eq!(8, bytes.len());
67+
Ok(Ok(8))
68+
}
3869
}

‎src/tools/miri/src/shims/unix/linux/foreign_items.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
5555
let result = this.epoll_ctl(epfd, op, fd, event)?;
5656
this.write_scalar(result, dest)?;
5757
}
58+
"epoll_wait" => {
59+
let [epfd, events, maxevents, timeout] =
60+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
61+
let result = this.epoll_wait(epfd, events, maxevents, timeout)?;
62+
this.write_scalar(result, dest)?;
63+
}
5864
"eventfd" => {
5965
let [val, flag] =
6066
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;

‎src/tools/miri/test-cargo-miri/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ fn main() {
2323
// (We rely on the test runner to always disable isolation when passing no arguments.)
2424
if std::env::args().len() <= 1 {
2525
fn host_to_target_path(path: String) -> PathBuf {
26-
use std::ffi::{CStr, CString};
26+
use std::ffi::{c_char, CStr, CString};
2727

2828
let path = CString::new(path).unwrap();
2929
let mut out = Vec::with_capacity(1024);
3030

3131
unsafe {
3232
extern "Rust" {
3333
fn miri_host_to_target_path(
34-
path: *const i8,
35-
out: *mut i8,
34+
path: *const c_char,
35+
out: *mut c_char,
3636
out_size: usize,
3737
) -> usize;
3838
}

‎src/tools/miri/test-cargo-miri/subcrate/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ fn main() {
55
println!("subcrate running");
66

77
fn host_to_target_path(path: String) -> PathBuf {
8-
use std::ffi::{CStr, CString};
8+
use std::ffi::{c_char, CStr, CString};
99

1010
let path = CString::new(path).unwrap();
1111
let mut out = Vec::with_capacity(1024);
1212

1313
unsafe {
1414
extern "Rust" {
1515
fn miri_host_to_target_path(
16-
path: *const i8,
17-
out: *mut i8,
16+
path: *const c_char,
17+
out: *mut c_char,
1818
out_size: usize,
1919
) -> usize;
2020
}

‎src/tools/miri/test-cargo-miri/subcrate/test.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ fn main() {
88
println!("subcrate testing");
99

1010
fn host_to_target_path(path: String) -> PathBuf {
11-
use std::ffi::{CStr, CString};
11+
use std::ffi::{c_char, CStr, CString};
1212

1313
let path = CString::new(path).unwrap();
1414
let mut out = Vec::with_capacity(1024);
1515

1616
unsafe {
1717
extern "Rust" {
1818
fn miri_host_to_target_path(
19-
path: *const i8,
20-
out: *mut i8,
19+
path: *const c_char,
20+
out: *mut c_char,
2121
out_size: usize,
2222
) -> usize;
2323
}

‎src/tools/miri/test_dependencies/Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change

‎src/tools/miri/test_dependencies/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ rand = { version = "0.8", features = ["small_rng"] }
1818

1919
[target.'cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))'.dependencies]
2020
page_size = "0.5"
21-
tokio = { version = "1.23", features = ["full"] }
21+
tokio = { version = "1.24", features = ["full"] }
2222

2323
[workspace]

‎src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#![allow(dead_code, unused_variables)]
55

6-
use std::{ptr, mem};
6+
use std::{mem, ptr};
77

88
#[repr(packed)]
99
struct Foo {

‎src/tools/miri/tests/pass-dep/shims/libc-fs.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![feature(io_error_uncategorized)]
66

77
use std::convert::TryInto;
8-
use std::ffi::{CStr, CString};
8+
use std::ffi::{c_char, CStr, CString};
99
use std::fs::{canonicalize, remove_dir_all, remove_file, File};
1010
use std::io::{Error, ErrorKind, Write};
1111
use std::os::unix::ffi::OsStrExt;
@@ -31,7 +31,11 @@ fn tmp() -> PathBuf {
3131

3232
unsafe {
3333
extern "Rust" {
34-
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
34+
fn miri_host_to_target_path(
35+
path: *const c_char,
36+
out: *mut c_char,
37+
out_size: usize,
38+
) -> usize;
3539
}
3640
let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
3741
assert_eq!(ret, 0);

‎src/tools/miri/tests/pass-dep/shims/libc-misc.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::os::unix::io::AsRawFd;
77
use std::path::PathBuf;
88

99
fn tmp() -> PathBuf {
10-
use std::ffi::{CStr, CString};
10+
use std::ffi::{c_char, CStr, CString};
1111

1212
let path = std::env::var("MIRI_TEMP")
1313
.unwrap_or_else(|_| std::env::temp_dir().into_os_string().into_string().unwrap());
@@ -17,7 +17,11 @@ fn tmp() -> PathBuf {
1717

1818
unsafe {
1919
extern "Rust" {
20-
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
20+
fn miri_host_to_target_path(
21+
path: *const c_char,
22+
out: *mut c_char,
23+
out_size: usize,
24+
) -> usize;
2125
}
2226
let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
2327
assert_eq!(ret, 0);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -Zmiri-backtrace=full
2+
//@only-target-x86_64-unknown-linux: support for tokio only on linux and x86
3+
4+
use tokio::time::{sleep, Duration, Instant};
5+
6+
#[tokio::main]
7+
async fn main() {
8+
let start = Instant::now();
9+
sleep(Duration::from_secs(1)).await;
10+
// It takes 96 millisecond to sleep for 1 millisecond
11+
// It takes 1025 millisecond to sleep for 1 second
12+
let time_elapsed = &start.elapsed().as_millis();
13+
assert!(time_elapsed > &1000, "{}", time_elapsed);
14+
}

‎src/tools/miri/tests/pass-dep/tokio_mvp.rs renamed to ‎src/tools/miri/tests/pass-dep/tokio/tokio_mvp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Need to disable preemption to stay on the supported MVP codepath in mio.
2-
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance -Zmiri-preemption-rate=0
2+
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
33
//@only-target-x86_64-unknown-linux: support for tokio exists only on linux and x86
44

55
#[tokio::main]

‎src/tools/miri/tests/pass/dyn-star.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#![feature(dyn_star)]
22
#![allow(incomplete_features)]
3+
#![feature(custom_inner_attributes)]
4+
// rustfmt destroys `dyn* Trait` syntax
5+
#![rustfmt::skip]
36

47
use std::fmt::{Debug, Display};
58

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use std::future::Future;
2+
use std::ptr;
3+
4+
// This test:
5+
// - Compares addresses of non-Copy data before and after moving it
6+
// - Writes to the pointer after it has moved across the await point
7+
//
8+
// This is only meant to assert current behavior, not guarantee that this is
9+
// how it should work in the future. In fact, upcoming changes to rustc
10+
// *should* break these tests.
11+
// See: https://github.com/rust-lang/rust/issues/62958
12+
async fn data_moved_async() {
13+
async fn helper(mut data: Vec<u8>, raw_pointer: *mut Vec<u8>) {
14+
let raw_pointer2 = ptr::addr_of_mut!(data);
15+
// `raw_pointer` points to the original location where the Vec was stored in the caller.
16+
// `data` is where that Vec (to be precise, its ptr+capacity+len on-stack data)
17+
// got moved to. Those will usually not be the same since the Vec got moved twice
18+
// (into the function call, and then into the generator upvar).
19+
assert_ne!(raw_pointer, raw_pointer2);
20+
unsafe {
21+
// This writes into the `x` in `data_moved_async`, re-initializing it.
22+
std::ptr::write(raw_pointer, vec![3]);
23+
}
24+
}
25+
// Vec<T> is not Copy
26+
let mut x: Vec<u8> = vec![2];
27+
let raw_pointer = ptr::addr_of_mut!(x);
28+
helper(x, raw_pointer).await;
29+
unsafe {
30+
assert_eq!(*raw_pointer, vec![3]);
31+
// Drop to prevent leak.
32+
std::ptr::drop_in_place(raw_pointer);
33+
}
34+
}
35+
36+
// Same thing as above, but non-async.
37+
fn data_moved() {
38+
fn helper(mut data: Vec<u8>, raw_pointer: *mut Vec<u8>) {
39+
let raw_pointer2 = ptr::addr_of_mut!(data);
40+
assert_ne!(raw_pointer, raw_pointer2);
41+
unsafe {
42+
std::ptr::write(raw_pointer, vec![3]);
43+
}
44+
}
45+
46+
let mut x: Vec<u8> = vec![2];
47+
let raw_pointer = ptr::addr_of_mut!(x);
48+
helper(x, raw_pointer);
49+
unsafe {
50+
assert_eq!(*raw_pointer, vec![3]);
51+
std::ptr::drop_in_place(raw_pointer);
52+
}
53+
}
54+
55+
fn run_fut<T>(fut: impl Future<Output = T>) -> T {
56+
use std::sync::Arc;
57+
use std::task::{Context, Poll, Wake, Waker};
58+
59+
struct MyWaker;
60+
impl Wake for MyWaker {
61+
fn wake(self: Arc<Self>) {
62+
unimplemented!()
63+
}
64+
}
65+
66+
let waker = Waker::from(Arc::new(MyWaker));
67+
let mut context = Context::from_waker(&waker);
68+
69+
let mut pinned = Box::pin(fut);
70+
loop {
71+
match pinned.as_mut().poll(&mut context) {
72+
Poll::Pending => continue,
73+
Poll::Ready(v) => return v,
74+
}
75+
}
76+
}
77+
78+
fn main() {
79+
run_fut(data_moved_async());
80+
data_moved();
81+
}

‎src/tools/miri/tests/pass/shims/fs.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#![feature(is_terminal)]
77

88
use std::collections::HashMap;
9-
use std::ffi::OsString;
9+
use std::ffi::{c_char, OsString};
1010
use std::fs::{
1111
canonicalize, create_dir, read_dir, read_link, remove_dir, remove_dir_all, remove_file, rename,
1212
File, OpenOptions,
@@ -39,7 +39,11 @@ fn host_to_target_path(path: String) -> PathBuf {
3939

4040
unsafe {
4141
extern "Rust" {
42-
fn miri_host_to_target_path(path: *const i8, out: *mut i8, out_size: usize) -> usize;
42+
fn miri_host_to_target_path(
43+
path: *const c_char,
44+
out: *mut c_char,
45+
out_size: usize,
46+
) -> usize;
4347
}
4448
let ret = miri_host_to_target_path(path.as_ptr(), out.as_mut_ptr(), out.capacity());
4549
assert_eq!(ret, 0);

0 commit comments

Comments
 (0)
Please sign in to comment.