Skip to content

Commit c430e50

Browse files
committed
Resolve merge conflicts
2 parents a815a42 + e23e0b2 commit c430e50

File tree

18 files changed

+196
-75
lines changed

18 files changed

+196
-75
lines changed

.github/workflows/ci.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,11 @@ jobs:
130130
ZULIP_API_TOKEN: ${{ secrets.ZULIP_API_TOKEN }}
131131
run: |
132132
~/.local/bin/zulip-send --stream miri --subject "Cron Job Failure" \
133-
--message 'Dear @**RalfJ** and @**oli**\n\nIt would appear that the Miri cron job build failed. Would you mind investigating this issue?\n\nThanks in advance!\nSincerely,\nThe Miri Cronjobs Bot' \
133+
--message 'Dear @**RalfJ** and @**oli**
134+
135+
It would appear that the Miri cron job build failed. Would you mind investigating this issue?
136+
137+
Thanks in advance!
138+
Sincerely,
139+
The Miri Cronjobs Bot' \
134140
--user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ environment variable:
198198
* `-Zmiri-disable-alignment-check` disables checking pointer alignment, so you
199199
can focus on other failures, but it means Miri can miss bugs in your program.
200200
Using this flag is **unsound**.
201+
* `-Zmiri-disable-data-race-detector` disables checking for data races. Using
202+
this flag is **unsound**.
201203
* `-Zmiri-disable-stacked-borrows` disables checking the experimental
202204
[Stacked Borrows] aliasing rules. This can make Miri run faster, but it also
203205
means no aliasing violations will be detected. Using this flag is **unsound**

cargo-miri/bin.rs

+110-44
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::env;
22
use std::ffi::OsString;
33
use std::fs::{self, File};
4+
use std::iter::TakeWhile;
45
use std::io::{self, BufRead, BufReader, BufWriter, Read, Write};
56
use std::ops::Not;
67
use std::path::{Path, PathBuf};
@@ -36,9 +37,9 @@ enum MiriCommand {
3637
Setup,
3738
}
3839

39-
/// The inforamtion Miri needs to run a crate. Stored as JSON when the crate is "compiled".
40+
/// The information to run a crate with the given environment.
4041
#[derive(Serialize, Deserialize)]
41-
struct CrateRunInfo {
42+
struct CrateRunEnv {
4243
/// The command-line arguments.
4344
args: Vec<String>,
4445
/// The environment.
@@ -49,6 +50,15 @@ struct CrateRunInfo {
4950
stdin: Vec<u8>,
5051
}
5152

53+
/// The information Miri needs to run a crate. Stored as JSON when the crate is "compiled".
54+
#[derive(Serialize, Deserialize)]
55+
enum CrateRunInfo {
56+
/// Run it with the given environment.
57+
RunWith(CrateRunEnv),
58+
/// Skip it as Miri does not support interpreting such kind of crates.
59+
SkipProcMacroTest,
60+
}
61+
5262
impl CrateRunInfo {
5363
/// Gather all the information we need.
5464
fn collect(args: env::Args) -> Self {
@@ -61,7 +71,7 @@ impl CrateRunInfo {
6171
std::io::stdin().lock().read_to_end(&mut stdin).expect("cannot read stdin");
6272
}
6373

64-
CrateRunInfo { args, env, current_dir, stdin }
74+
Self::RunWith(CrateRunEnv { args, env, current_dir, stdin })
6575
}
6676

6777
fn store(&self, filename: &Path) {
@@ -97,31 +107,50 @@ fn has_arg_flag(name: &str) -> bool {
97107
args.any(|val| val == name)
98108
}
99109

100-
/// Gets the value of a `--flag`.
101-
fn get_arg_flag_value(name: &str) -> Option<String> {
102-
// Stop searching at `--`.
103-
let mut args = std::env::args().take_while(|val| val != "--");
104-
loop {
105-
let arg = match args.next() {
106-
Some(arg) => arg,
107-
None => return None,
108-
};
109-
if !arg.starts_with(name) {
110-
continue;
110+
/// Yields all values of command line flag `name`.
111+
struct ArgFlagValueIter<'a> {
112+
args: TakeWhile<env::Args, fn(&String) -> bool>,
113+
name: &'a str,
114+
}
115+
116+
impl<'a> ArgFlagValueIter<'a> {
117+
fn new(name: &'a str) -> Self {
118+
Self {
119+
// Stop searching at `--`.
120+
args: env::args().take_while(|val| val != "--"),
121+
name,
111122
}
112-
// Strip leading `name`.
113-
let suffix = &arg[name.len()..];
114-
if suffix.is_empty() {
115-
// This argument is exactly `name`; the next one is the value.
116-
return args.next();
117-
} else if suffix.starts_with('=') {
118-
// This argument is `name=value`; get the value.
119-
// Strip leading `=`.
120-
return Some(suffix[1..].to_owned());
123+
}
124+
}
125+
126+
impl Iterator for ArgFlagValueIter<'_> {
127+
type Item = String;
128+
129+
fn next(&mut self) -> Option<Self::Item> {
130+
loop {
131+
let arg = self.args.next()?;
132+
if !arg.starts_with(self.name) {
133+
continue;
134+
}
135+
// Strip leading `name`.
136+
let suffix = &arg[self.name.len()..];
137+
if suffix.is_empty() {
138+
// This argument is exactly `name`; the next one is the value.
139+
return self.args.next();
140+
} else if suffix.starts_with('=') {
141+
// This argument is `name=value`; get the value.
142+
// Strip leading `=`.
143+
return Some(suffix[1..].to_owned());
144+
}
121145
}
122146
}
123147
}
124148

149+
/// Gets the value of a `--flag`.
150+
fn get_arg_flag_value(name: &str) -> Option<String> {
151+
ArgFlagValueIter::new(name).next()
152+
}
153+
125154
/// Returns the path to the `miri` binary
126155
fn find_miri() -> PathBuf {
127156
if let Some(path) = env::var_os("MIRI") {
@@ -460,14 +489,15 @@ fn phase_cargo_miri(mut args: env::Args) {
460489
// This is needed to make the `CARGO_TARGET_*_RUNNER` env var do something,
461490
// and it later helps us detect which crates are proc-macro/build-script
462491
// (host crates) and which crates are needed for the program itself.
463-
let target = if let Some(target) = get_arg_flag_value("--target") {
492+
let host = version_info().host;
493+
let target = get_arg_flag_value("--target");
494+
let target = if let Some(ref target) = target {
464495
target
465496
} else {
466497
// No target given. Pick default and tell cargo about it.
467-
let host = version_info().host;
468498
cmd.arg("--target");
469499
cmd.arg(&host);
470-
host
500+
&host
471501
};
472502

473503
// Forward all further arguments. We do some processing here because we want to
@@ -519,17 +549,27 @@ fn phase_cargo_miri(mut args: env::Args) {
519549
}
520550
cmd.env("RUSTC_WRAPPER", &cargo_miri_path);
521551

522-
// Set the runner for the current target to us as well, so we can interpret the binaries.
523-
let runner_env_name = format!("CARGO_TARGET_{}_RUNNER", target.to_uppercase().replace('-', "_"));
524-
cmd.env(&runner_env_name, &cargo_miri_path);
552+
let runner_env_name = |triple: &str| {
553+
format!("CARGO_TARGET_{}_RUNNER", triple.to_uppercase().replace('-', "_"))
554+
};
555+
let host_runner_env_name = runner_env_name(&host);
556+
let target_runner_env_name = runner_env_name(target);
557+
// Set the target runner to us, so we can interpret the binaries.
558+
cmd.env(&target_runner_env_name, &cargo_miri_path);
559+
// Unit tests of `proc-macro` crates are run on the host, so we set the host runner to
560+
// us in order to skip them.
561+
cmd.env(&host_runner_env_name, &cargo_miri_path);
525562

526563
// Set rustdoc to us as well, so we can make it do nothing (see issue #584).
527564
cmd.env("RUSTDOC", &cargo_miri_path);
528565

529566
// Run cargo.
530567
if verbose {
531568
eprintln!("[cargo-miri miri] RUSTC_WRAPPER={:?}", cargo_miri_path);
532-
eprintln!("[cargo-miri miri] {}={:?}", runner_env_name, cargo_miri_path);
569+
eprintln!("[cargo-miri miri] {}={:?}", target_runner_env_name, cargo_miri_path);
570+
if *target != host {
571+
eprintln!("[cargo-miri miri] {}={:?}", host_runner_env_name, cargo_miri_path);
572+
}
533573
eprintln!("[cargo-miri miri] RUSTDOC={:?}", cargo_miri_path);
534574
eprintln!("[cargo-miri miri] {:?}", cmd);
535575
cmd.env("MIRI_VERBOSE", ""); // This makes the other phases verbose.
@@ -597,28 +637,38 @@ fn phase_cargo_rustc(args: env::Args) {
597637
_ => {},
598638
}
599639

600-
if !print && target_crate && is_runnable_crate() {
601-
// This is the binary or test crate that we want to interpret under Miri.
602-
// But we cannot run it here, as cargo invoked us as a compiler -- our stdin and stdout are not
603-
// like we want them.
604-
// Instead of compiling, we write JSON into the output file with all the relevant command-line flags
605-
// and environment variables; this is used when cargo calls us again in the CARGO_TARGET_RUNNER phase.
606-
let info = CrateRunInfo::collect(args);
640+
let store_json = |info: &CrateRunInfo| {
607641
let filename = out_filename("", "");
608642
if verbose {
609643
eprintln!("[cargo-miri rustc] writing run info to `{}`", filename.display());
610644
}
611-
612645
info.store(&filename);
613646
// For Windows, do the same thing again with `.exe` appended to the filename.
614647
// (Need to do this here as cargo moves that "binary" to a different place before running it.)
615648
info.store(&out_filename("", ".exe"));
649+
};
650+
651+
let runnable_crate = !print && is_runnable_crate();
652+
653+
if runnable_crate && target_crate {
654+
// This is the binary or test crate that we want to interpret under Miri.
655+
// But we cannot run it here, as cargo invoked us as a compiler -- our stdin and stdout are not
656+
// like we want them.
657+
// Instead of compiling, we write JSON into the output file with all the relevant command-line flags
658+
// and environment variables; this is used when cargo calls us again in the CARGO_TARGET_RUNNER phase.
659+
let info = CrateRunInfo::collect(args);
660+
store_json(&info);
616661

617662
// Rustdoc expects us to exit with an error code if the test is marked as `compile_fail`,
618663
// just creating the JSON file is not enough: we need to detect syntax errors,
619664
// so we need to run Miri with `MIRI_BE_RUSTC` for a check-only build.
620665
if std::env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some() {
621666
let mut cmd = miri();
667+
let env = if let CrateRunInfo::RunWith(env) = info {
668+
env
669+
} else {
670+
return;
671+
};
622672

623673
// use our own sysroot
624674
if !has_arg_flag("--sysroot") {
@@ -628,28 +678,36 @@ fn phase_cargo_rustc(args: env::Args) {
628678
}
629679

630680
// ensure --emit argument for a check-only build is present
631-
if let Some(i) = info.args.iter().position(|arg| arg.starts_with("--emit=")) {
681+
if let Some(i) = env.args.iter().position(|arg| arg.starts_with("--emit=")) {
632682
// We need to make sure we're not producing a binary that overwrites the JSON file.
633683
// rustdoc should only ever pass an --emit=metadata argument for tests marked as `no_run`:
634-
assert_eq!(info.args[i], "--emit=metadata");
684+
assert_eq!(env.args[i], "--emit=metadata");
635685
} else {
636686
cmd.arg("--emit=dep-info,metadata");
637687
}
638688

639-
cmd.args(info.args);
689+
cmd.args(env.args);
640690
cmd.env("MIRI_BE_RUSTC", "1");
641691

642692
if verbose {
643-
eprintln!("[cargo-miri rustc] captured input:\n{}", std::str::from_utf8(&info.stdin).unwrap());
693+
eprintln!("[cargo-miri rustc] captured input:\n{}", std::str::from_utf8(&env.stdin).unwrap());
644694
eprintln!("[cargo-miri rustc] {:?}", cmd);
645695
}
646696

647-
exec_with_pipe(cmd, &info.stdin);
697+
exec_with_pipe(cmd, &env.stdin);
648698
}
649699

650700
return;
651701
}
652702

703+
if runnable_crate && ArgFlagValueIter::new("--extern").any(|krate| krate == "proc_macro") {
704+
// This is a "runnable" `proc-macro` crate (unit tests). We do not support
705+
// interpreting that under Miri now, so we write a JSON file to (display a
706+
// helpful message and) skip it in the runner phase.
707+
store_json(&CrateRunInfo::SkipProcMacroTest);
708+
return;
709+
}
710+
653711
let mut cmd = miri();
654712
let mut emit_link_hack = false;
655713
// Arguments are treated very differently depending on whether this crate is
@@ -726,8 +784,16 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
726784
let file = File::open(&binary)
727785
.unwrap_or_else(|_| show_error(format!("file {:?} not found or `cargo-miri` invoked incorrectly; please only invoke this binary through `cargo miri`", binary)));
728786
let file = BufReader::new(file);
729-
let info: CrateRunInfo = serde_json::from_reader(file)
787+
788+
let info = serde_json::from_reader(file)
730789
.unwrap_or_else(|_| show_error(format!("file {:?} contains outdated or invalid JSON; try `cargo clean`", binary)));
790+
let info = match info {
791+
CrateRunInfo::RunWith(info) => info,
792+
CrateRunInfo::SkipProcMacroTest => {
793+
eprintln!("Running unit tests of `proc-macro` crates is not currently supported by Miri.");
794+
return;
795+
}
796+
};
731797

732798
let mut cmd = miri();
733799

ci.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ run_tests
4747
case $HOST_TARGET in
4848
x86_64-unknown-linux-gnu)
4949
MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
50-
MIRI_TEST_TARGET=x86_64-apple-darwin run_tests
50+
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
5151
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
5252
;;
5353
x86_64-apple-darwin)

rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
dc1eee2f256efbd1d3b50b6b090232f81cac6d72
1+
78e22069d018e83915201c8a218a0a94227f6420

src/shims/foreign_items.rs

+12
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
484484
let &[] = check_arg_count(args)?;
485485
this.yield_active_thread();
486486
}
487+
"llvm.aarch64.hint" if this.tcx.sess.target.arch == "aarch64" => {
488+
let &[hint] = check_arg_count(args)?;
489+
let hint = this.read_scalar(hint)?.to_i32()?;
490+
match hint {
491+
1 => { // HINT_YIELD
492+
this.yield_active_thread();
493+
}
494+
_ => {
495+
throw_unsup_format!("unsupported llvm.aarch64.hint argument {}", hint);
496+
}
497+
}
498+
}
487499

488500
// Platform-specific shims
489501
_ => match this.tcx.sess.target.os.as_str() {

src/shims/posix/foreign_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
180180

181181
let sysconfs = &[
182182
("_SC_PAGESIZE", Scalar::from_int(PAGE_SIZE, this.pointer_size())),
183+
("_SC_NPROCESSORS_CONF", Scalar::from_int(NUM_CPUS, this.pointer_size())),
183184
("_SC_NPROCESSORS_ONLN", Scalar::from_int(NUM_CPUS, this.pointer_size())),
184185
];
185186
let mut result = None;

src/shims/posix/macos/foreign_items.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2525
}
2626

2727
// File related shims
28-
"close$NOCANCEL" => {
28+
"close" | "close$NOCANCEL" => {
2929
let &[result] = check_arg_count(args)?;
3030
let result = this.close(result)?;
3131
this.write_scalar(Scalar::from_i32(result), dest)?;
3232
}
33-
"stat$INODE64" => {
33+
"stat" | "stat$INODE64" => {
3434
let &[path, buf] = check_arg_count(args)?;
3535
let result = this.macos_stat(path, buf)?;
3636
this.write_scalar(Scalar::from_i32(result), dest)?;
3737
}
38-
"lstat$INODE64" => {
38+
"lstat" | "lstat$INODE64" => {
3939
let &[path, buf] = check_arg_count(args)?;
4040
let result = this.macos_lstat(path, buf)?;
4141
this.write_scalar(Scalar::from_i32(result), dest)?;
4242
}
43-
"fstat$INODE64" => {
43+
"fstat" | "fstat$INODE64" => {
4444
let &[fd, buf] = check_arg_count(args)?;
4545
let result = this.macos_fstat(fd, buf)?;
4646
this.write_scalar(Scalar::from_i32(result), dest)?;
4747
}
48-
"opendir$INODE64" => {
48+
"opendir" | "opendir$INODE64" => {
4949
let &[name] = check_arg_count(args)?;
5050
let result = this.opendir(name)?;
5151
this.write_scalar(result, dest)?;
5252
}
53-
"readdir_r$INODE64" => {
53+
"readdir_r" | "readdir_r$INODE64" => {
5454
let &[dirp, entry, result] = check_arg_count(args)?;
5555
let result = this.macos_readdir_r(dirp, entry, result)?;
5656
this.write_scalar(Scalar::from_i32(result), dest)?;

src/shims/windows/dlsym.rs

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ impl Dlsym {
2727
"AcquireSRWLockShared" => Some(Dlsym::AcquireSRWLockShared),
2828
"ReleaseSRWLockShared" => Some(Dlsym::ReleaseSRWLockShared),
2929
"TryAcquireSRWLockShared" => Some(Dlsym::TryAcquireSRWLockShared),
30-
"SetThreadStackGuarantee" => None,
3130
"GetSystemTimePreciseAsFileTime" => None,
3231
_ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
3332
})

0 commit comments

Comments
 (0)