Rollup merge of #129973 - jieyouxu:rework-rmake-stdio, r=Kobzol
run_make_support: rename `Command::stdin` to `stdin_buf` and add `std{in,out,err}` config helpers Previously `Command::stdin` was actually just a stdin buffer helper, but this is different from `std::process::Command::stdin`. This is needlessly confusing, and blocks support to add `std{in,out,err}` config helpers that tests may want to use to e.g. redirect to `/dev/ptmx`.
This commit is contained in:
commit
fee6c0a683
22 changed files with 116 additions and 46 deletions
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
/// This is a custom command wrapper that simplifies working with commands and makes it easier to
|
/// This is a custom command wrapper that simplifies working with commands and makes it easier to
|
||||||
/// ensure that we check the exit status of executed processes.
|
/// ensure that we check the exit status of executed processes.
|
||||||
///
|
///
|
||||||
/// # A [`Command`] must be executed
|
/// # A [`Command`] must be executed exactly once
|
||||||
///
|
///
|
||||||
/// A [`Command`] is armed by a [`DropBomb`] on construction to enforce that it will be executed. If
|
/// A [`Command`] is armed by a [`DropBomb`] on construction to enforce that it will be executed. If
|
||||||
/// a [`Command`] is constructed but never executed, the drop bomb will explode and cause the test
|
/// a [`Command`] is constructed but never executed, the drop bomb will explode and cause the test
|
||||||
|
@ -23,26 +23,73 @@ use crate::{
|
||||||
/// containing constructed but never executed commands is dangerous because it can give a false
|
/// containing constructed but never executed commands is dangerous because it can give a false
|
||||||
/// sense of confidence.
|
/// sense of confidence.
|
||||||
///
|
///
|
||||||
|
/// Each [`Command`] invocation can also only be executed once, because we want to enforce
|
||||||
|
/// `std{in,out,err}` config via [`std::process::Stdio`] but [`std::process::Stdio`] is not
|
||||||
|
/// cloneable.
|
||||||
|
///
|
||||||
|
/// In this sense, [`Command`] exhibits linear type semantics but enforced at run-time.
|
||||||
|
///
|
||||||
/// [`run`]: Self::run
|
/// [`run`]: Self::run
|
||||||
/// [`run_fail`]: Self::run_fail
|
/// [`run_fail`]: Self::run_fail
|
||||||
/// [`run_unchecked`]: Self::run_unchecked
|
/// [`run_unchecked`]: Self::run_unchecked
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Command {
|
pub struct Command {
|
||||||
cmd: StdCommand,
|
cmd: StdCommand,
|
||||||
stdin: Option<Box<[u8]>>,
|
// Convience for providing a quick stdin buffer.
|
||||||
|
stdin_buf: Option<Box<[u8]>>,
|
||||||
|
|
||||||
|
// Configurations for child process's std{in,out,err} handles.
|
||||||
|
stdin: Option<Stdio>,
|
||||||
|
stdout: Option<Stdio>,
|
||||||
|
stderr: Option<Stdio>,
|
||||||
|
|
||||||
|
// Emulate linear type semantics.
|
||||||
drop_bomb: DropBomb,
|
drop_bomb: DropBomb,
|
||||||
|
already_executed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn new<P: AsRef<OsStr>>(program: P) -> Self {
|
pub fn new<P: AsRef<OsStr>>(program: P) -> Self {
|
||||||
let program = program.as_ref();
|
let program = program.as_ref();
|
||||||
Self { cmd: StdCommand::new(program), stdin: None, drop_bomb: DropBomb::arm(program) }
|
Self {
|
||||||
|
cmd: StdCommand::new(program),
|
||||||
|
stdin_buf: None,
|
||||||
|
drop_bomb: DropBomb::arm(program),
|
||||||
|
stdin: None,
|
||||||
|
stdout: None,
|
||||||
|
stderr: None,
|
||||||
|
already_executed: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify a stdin input
|
/// Specify a stdin input buffer. This is a convenience helper,
|
||||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||||
self.stdin = Some(input.as_ref().to_vec().into_boxed_slice());
|
self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the child process’s standard input (stdin) handle.
|
||||||
|
///
|
||||||
|
/// See [`std::process::Command::stdin`].
|
||||||
|
pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self {
|
||||||
|
self.stdin = Some(cfg.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the child process’s standard output (stdout) handle.
|
||||||
|
///
|
||||||
|
/// See [`std::process::Command::stdout`].
|
||||||
|
pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self {
|
||||||
|
self.stdout = Some(cfg.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configuration for the child process’s standard error (stderr) handle.
|
||||||
|
///
|
||||||
|
/// See [`std::process::Command::stderr`].
|
||||||
|
pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Self {
|
||||||
|
self.stderr = Some(cfg.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +152,8 @@ impl Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the constructed command and assert that it is successfully run.
|
/// Run the constructed command and assert that it is successfully run.
|
||||||
|
///
|
||||||
|
/// By default, std{in,out,err} are [`Stdio::piped()`].
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn run(&mut self) -> CompletedProcess {
|
pub fn run(&mut self) -> CompletedProcess {
|
||||||
let output = self.command_output();
|
let output = self.command_output();
|
||||||
|
@ -115,6 +164,8 @@ impl Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the constructed command and assert that it does not successfully run.
|
/// Run the constructed command and assert that it does not successfully run.
|
||||||
|
///
|
||||||
|
/// By default, std{in,out,err} are [`Stdio::piped()`].
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn run_fail(&mut self) -> CompletedProcess {
|
pub fn run_fail(&mut self) -> CompletedProcess {
|
||||||
let output = self.command_output();
|
let output = self.command_output();
|
||||||
|
@ -124,10 +175,10 @@ impl Command {
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the command but do not check its exit status.
|
/// Run the command but do not check its exit status. Only use if you explicitly don't care
|
||||||
/// Only use if you explicitly don't care about the exit status.
|
/// about the exit status.
|
||||||
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
|
///
|
||||||
/// whenever possible.
|
/// Prefer to use [`Self::run`] and [`Self::run_fail`] whenever possible.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn run_unchecked(&mut self) -> CompletedProcess {
|
pub fn run_unchecked(&mut self) -> CompletedProcess {
|
||||||
self.command_output()
|
self.command_output()
|
||||||
|
@ -135,13 +186,19 @@ impl Command {
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn command_output(&mut self) -> CompletedProcess {
|
fn command_output(&mut self) -> CompletedProcess {
|
||||||
|
if self.already_executed {
|
||||||
|
panic!("command was already executed");
|
||||||
|
} else {
|
||||||
|
self.already_executed = true;
|
||||||
|
}
|
||||||
|
|
||||||
self.drop_bomb.defuse();
|
self.drop_bomb.defuse();
|
||||||
// let's make sure we piped all the input and outputs
|
// let's make sure we piped all the input and outputs
|
||||||
self.cmd.stdin(Stdio::piped());
|
self.cmd.stdin(self.stdin.take().unwrap_or(Stdio::piped()));
|
||||||
self.cmd.stdout(Stdio::piped());
|
self.cmd.stdout(self.stdout.take().unwrap_or(Stdio::piped()));
|
||||||
self.cmd.stderr(Stdio::piped());
|
self.cmd.stderr(self.stderr.take().unwrap_or(Stdio::piped()));
|
||||||
|
|
||||||
let output = if let Some(input) = &self.stdin {
|
let output = if let Some(input) = &self.stdin_buf {
|
||||||
let mut child = self.cmd.spawn().unwrap();
|
let mut child = self.cmd.spawn().unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -227,9 +227,10 @@ impl LlvmFilecheck {
|
||||||
Self { cmd }
|
Self { cmd }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pipe a read file into standard input containing patterns that will be matched against the .patterns(path) call.
|
/// Provide a buffer representing standard input containing patterns that will be matched
|
||||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
/// against the `.patterns(path)` call.
|
||||||
self.cmd.stdin(input);
|
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||||
|
self.cmd.stdin_buf(input);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -291,9 +291,9 @@ impl Rustc {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify a stdin input
|
/// Specify a stdin input buffer.
|
||||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||||
self.cmd.stdin(input);
|
self.cmd.stdin_buf(input);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,9 +85,9 @@ impl Rustdoc {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify a stdin input
|
/// Specify a stdin input buffer.
|
||||||
pub fn stdin<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
|
||||||
self.cmd.stdin(input);
|
self.cmd.stdin_buf(input);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub mod rfs {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-exports of third-party library crates.
|
// Re-exports of third-party library crates.
|
||||||
|
// tidy-alphabetical-start
|
||||||
pub use bstr;
|
pub use bstr;
|
||||||
pub use gimli;
|
pub use gimli;
|
||||||
pub use libc;
|
pub use libc;
|
||||||
|
@ -41,6 +42,7 @@ pub use object;
|
||||||
pub use regex;
|
pub use regex;
|
||||||
pub use serde_json;
|
pub use serde_json;
|
||||||
pub use wasmparser;
|
pub use wasmparser;
|
||||||
|
// tidy-alphabetical-end
|
||||||
|
|
||||||
// Re-exports of external dependencies.
|
// Re-exports of external dependencies.
|
||||||
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
|
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
use run_make_support::rustc;
|
use run_make_support::rustc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let output = rustc().output("").stdin(b"fn main() {}").run_fail();
|
let output = rustc().output("").stdin_buf(b"fn main() {}").run_fail();
|
||||||
output.assert_stderr_not_contains("panic");
|
output.assert_stderr_not_contains("panic");
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn main() {
|
||||||
|
|
||||||
rustc()
|
rustc()
|
||||||
.arg("-")
|
.arg("-")
|
||||||
.stdin("fn main() {}")
|
.stdin_buf("fn main() {}")
|
||||||
.emit("link,obj")
|
.emit("link,obj")
|
||||||
.arg("-Csave-temps")
|
.arg("-Csave-temps")
|
||||||
.target(target)
|
.target(target)
|
||||||
|
|
|
@ -8,6 +8,6 @@
|
||||||
use run_make_support::{run, rustc};
|
use run_make_support::{run, rustc};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rustc().arg("-").stdin("fn main() {}").run();
|
rustc().arg("-").stdin_buf("fn main() {}").run();
|
||||||
run("rust_out");
|
run("rust_out");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn run_tests(extra_args: &[&str], expected_file: &str) {
|
||||||
.run_fail();
|
.run_fail();
|
||||||
let test_stdout = &cmd_out.stdout_utf8();
|
let test_stdout = &cmd_out.stdout_utf8();
|
||||||
|
|
||||||
python_command().arg("validate_junit.py").stdin(test_stdout).run();
|
python_command().arg("validate_junit.py").stdin_buf(test_stdout).run();
|
||||||
|
|
||||||
diff()
|
diff()
|
||||||
.expected_file(expected_file)
|
.expected_file(expected_file)
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn main() {
|
||||||
.codegen_units(16)
|
.codegen_units(16)
|
||||||
.opt_level("2")
|
.opt_level("2")
|
||||||
.target(&env_var("TARGET"))
|
.target(&env_var("TARGET"))
|
||||||
.stdin("fn main(){}")
|
.stdin_buf("fn main(){}")
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
// `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR
|
// `llvm-dis` is used here since `--emit=llvm-ir` does not emit LLVM IR
|
||||||
|
|
|
@ -11,8 +11,8 @@ fn main() {
|
||||||
let p = cwd();
|
let p = cwd();
|
||||||
path_bc = p.join("nonexistant_dir_bc");
|
path_bc = p.join("nonexistant_dir_bc");
|
||||||
path_ir = p.join("nonexistant_dir_ir");
|
path_ir = p.join("nonexistant_dir_ir");
|
||||||
rustc().input("-").stdin("fn main() {}").out_dir(&path_bc).emit("llvm-bc").run();
|
rustc().input("-").stdin_buf("fn main() {}").out_dir(&path_bc).emit("llvm-bc").run();
|
||||||
rustc().input("-").stdin("fn main() {}").out_dir(&path_ir).emit("llvm-ir").run();
|
rustc().input("-").stdin_buf("fn main() {}").out_dir(&path_ir).emit("llvm-ir").run();
|
||||||
assert!(path_bc.exists());
|
assert!(path_bc.exists());
|
||||||
assert!(path_ir.exists());
|
assert!(path_ir.exists());
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,5 +9,5 @@ use run_make_support::{llvm_filecheck, rfs, rustc};
|
||||||
fn main() {
|
fn main() {
|
||||||
rustc().input("no_builtins.rs").emit("link").run();
|
rustc().input("no_builtins.rs").emit("link").run();
|
||||||
rustc().input("main.rs").emit("llvm-ir").run();
|
rustc().input("main.rs").emit("llvm-ir").run();
|
||||||
llvm_filecheck().patterns("filecheck.main.txt").stdin(rfs::read("main.ll")).run();
|
llvm_filecheck().patterns("filecheck.main.txt").stdin_buf(rfs::read("main.ll")).run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,8 @@ fn main() {
|
||||||
.codegen_units(1)
|
.codegen_units(1)
|
||||||
.emit("llvm-ir")
|
.emit("llvm-ir")
|
||||||
.run();
|
.run();
|
||||||
llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
|
llvm_filecheck()
|
||||||
|
.patterns("filecheck-patterns.txt")
|
||||||
|
.stdin_buf(rfs::read("interesting.ll"))
|
||||||
|
.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,5 +29,8 @@ fn main() {
|
||||||
.codegen_units(1)
|
.codegen_units(1)
|
||||||
.emit("llvm-ir")
|
.emit("llvm-ir")
|
||||||
.run();
|
.run();
|
||||||
llvm_filecheck().patterns("filecheck-patterns.txt").stdin(rfs::read("interesting.ll")).run();
|
llvm_filecheck()
|
||||||
|
.patterns("filecheck-patterns.txt")
|
||||||
|
.stdin_buf(rfs::read("interesting.ll"))
|
||||||
|
.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,5 +51,5 @@ fn main() {
|
||||||
let lines: Vec<_> = ir.lines().rev().collect();
|
let lines: Vec<_> = ir.lines().rev().collect();
|
||||||
let mut reversed_ir = lines.join("\n");
|
let mut reversed_ir = lines.join("\n");
|
||||||
reversed_ir.push('\n');
|
reversed_ir.push('\n');
|
||||||
llvm_filecheck().patterns("filecheck-patterns.txt").stdin(reversed_ir.as_bytes()).run();
|
llvm_filecheck().patterns("filecheck-patterns.txt").stdin_buf(reversed_ir.as_bytes()).run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use run_make_support::{run, rustc};
|
use run_make_support::{run, rustc};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
rustc().stdin(b"fn main(){}").arg("-Zno-link").arg("-").run();
|
rustc().stdin_buf(b"fn main(){}").arg("-Zno-link").arg("-").run();
|
||||||
rustc().arg("-Zlink-only").input("rust_out.rlink").run();
|
rustc().arg("-Zlink-only").input("rust_out.rlink").run();
|
||||||
run("rust_out");
|
run("rust_out");
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn ok_compiler_version(compiler: &str) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
let compiler_output =
|
let compiler_output =
|
||||||
cmd(compiler).stdin(trigger).arg("-").arg("-E").arg("-x").arg("c").run().stdout_utf8();
|
cmd(compiler).stdin_buf(trigger).arg("-").arg("-E").arg("-x").arg("c").run().stdout_utf8();
|
||||||
let re = Regex::new(r"(?m)^(\d+)").unwrap();
|
let re = Regex::new(r"(?m)^(\d+)").unwrap();
|
||||||
let version: u32 =
|
let version: u32 =
|
||||||
re.captures(&compiler_output).unwrap().get(1).unwrap().as_str().parse().unwrap();
|
re.captures(&compiler_output).unwrap().get(1).unwrap().as_str().parse().unwrap();
|
||||||
|
|
|
@ -14,7 +14,7 @@ const NOT_UTF8: &[u8] = &[0xff, 0xff, 0xff];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// echo $HELLO_WORLD | rustc -
|
// echo $HELLO_WORLD | rustc -
|
||||||
rustc().arg("-").stdin(HELLO_WORLD).run();
|
rustc().arg("-").stdin_buf(HELLO_WORLD).run();
|
||||||
assert!(
|
assert!(
|
||||||
PathBuf::from(if !is_windows() { "rust_out" } else { "rust_out.exe" })
|
PathBuf::from(if !is_windows() { "rust_out" } else { "rust_out.exe" })
|
||||||
.try_exists()
|
.try_exists()
|
||||||
|
@ -22,7 +22,7 @@ fn main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// echo $NOT_UTF8 | rustc -
|
// echo $NOT_UTF8 | rustc -
|
||||||
rustc().arg("-").stdin(NOT_UTF8).run_fail().assert_stderr_contains(
|
rustc().arg("-").stdin_buf(NOT_UTF8).run_fail().assert_stderr_contains(
|
||||||
"error: couldn't read from stdin, as it did not contain valid UTF-8",
|
"error: couldn't read from stdin, as it did not contain valid UTF-8",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,11 @@ fn main() {
|
||||||
let out_dir = PathBuf::from("doc");
|
let out_dir = PathBuf::from("doc");
|
||||||
|
|
||||||
// rustdoc -
|
// rustdoc -
|
||||||
rustdoc().arg("-").out_dir(&out_dir).stdin(INPUT).run();
|
rustdoc().arg("-").out_dir(&out_dir).stdin_buf(INPUT).run();
|
||||||
assert!(out_dir.join("rust_out/struct.F.html").try_exists().unwrap());
|
assert!(out_dir.join("rust_out/struct.F.html").try_exists().unwrap());
|
||||||
|
|
||||||
// rustdoc --test -
|
// rustdoc --test -
|
||||||
rustdoc().arg("--test").arg("-").stdin(INPUT).run();
|
rustdoc().arg("--test").arg("-").stdin_buf(INPUT).run();
|
||||||
|
|
||||||
// rustdoc file.rs -
|
// rustdoc file.rs -
|
||||||
rustdoc().arg("file.rs").arg("-").run_fail();
|
rustdoc().arg("file.rs").arg("-").run_fail();
|
||||||
|
|
|
@ -34,7 +34,7 @@ fn check_crate_is_unstable(cr: &Crate) {
|
||||||
.target(target())
|
.target(target())
|
||||||
.extern_(name, path)
|
.extern_(name, path)
|
||||||
.input("-")
|
.input("-")
|
||||||
.stdin(format!("extern crate {name};"))
|
.stdin_buf(format!("extern crate {name};"))
|
||||||
.run_fail();
|
.run_fail();
|
||||||
|
|
||||||
// Make sure it failed for the intended reason, not some other reason.
|
// Make sure it failed for the intended reason, not some other reason.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
use run_make_support::{diff, rustc};
|
use run_make_support::{diff, rustc};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let out = rustc().crate_type("rlib").stdin(b"mod unknown;").arg("-").run_fail();
|
let out = rustc().crate_type("rlib").stdin_buf(b"mod unknown;").arg("-").run_fail();
|
||||||
diff()
|
diff()
|
||||||
.actual_text("actual-stdout", out.stdout_utf8())
|
.actual_text("actual-stdout", out.stdout_utf8())
|
||||||
.expected_file("unknown-mod.stdout")
|
.expected_file("unknown-mod.stdout")
|
||||||
|
|
|
@ -78,19 +78,23 @@ fn check(func_re: &str, mut checks: &str) {
|
||||||
// This is because frame pointers are optional, and them being enabled requires
|
// This is because frame pointers are optional, and them being enabled requires
|
||||||
// an additional `popq` in the pattern checking file.
|
// an additional `popq` in the pattern checking file.
|
||||||
if func_re == "std::io::stdio::_print::[[:alnum:]]+" {
|
if func_re == "std::io::stdio::_print::[[:alnum:]]+" {
|
||||||
let output = llvm_filecheck().stdin(&dump).patterns(checks).run_unchecked();
|
let output = llvm_filecheck().stdin_buf(&dump).patterns(checks).run_unchecked();
|
||||||
if !output.status().success() {
|
if !output.status().success() {
|
||||||
checks = "print.without_frame_pointers.checks";
|
checks = "print.without_frame_pointers.checks";
|
||||||
llvm_filecheck().stdin(&dump).patterns(checks).run();
|
llvm_filecheck().stdin_buf(&dump).patterns(checks).run();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
llvm_filecheck().stdin(&dump).patterns(checks).run();
|
llvm_filecheck().stdin_buf(&dump).patterns(checks).run();
|
||||||
}
|
}
|
||||||
if !["rust_plus_one_global_asm", "cmake_plus_one_c_global_asm", "cmake_plus_one_cxx_global_asm"]
|
if !["rust_plus_one_global_asm", "cmake_plus_one_c_global_asm", "cmake_plus_one_cxx_global_asm"]
|
||||||
.contains(&func_re)
|
.contains(&func_re)
|
||||||
{
|
{
|
||||||
// The assembler cannot avoid explicit `ret` instructions. Sequences
|
// The assembler cannot avoid explicit `ret` instructions. Sequences
|
||||||
// of `shlq $0x0, (%rsp); lfence; retq` are used instead.
|
// of `shlq $0x0, (%rsp); lfence; retq` are used instead.
|
||||||
llvm_filecheck().args(&["--implicit-check-not", "ret"]).stdin(dump).patterns(checks).run();
|
llvm_filecheck()
|
||||||
|
.args(&["--implicit-check-not", "ret"])
|
||||||
|
.stdin_buf(dump)
|
||||||
|
.patterns(checks)
|
||||||
|
.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue