summaryrefslogtreecommitdiffstats
path: root/src/tools/compiletest
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/compiletest')
-rw-r--r--src/tools/compiletest/src/common.rs51
-rw-r--r--src/tools/compiletest/src/header.rs2
-rw-r--r--src/tools/compiletest/src/header/cfg.rs12
-rw-r--r--src/tools/compiletest/src/header/tests.rs5
-rw-r--r--src/tools/compiletest/src/lib.rs3
-rw-r--r--src/tools/compiletest/src/runtest.rs88
6 files changed, 107 insertions, 54 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 1e9684555..c45c0b3c6 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -242,6 +242,9 @@ pub struct Config {
/// Run ignored tests
pub run_ignored: bool,
+ /// Whether to run tests with `ignore-debug` header
+ pub with_debug_assertions: bool,
+
/// Only run tests that match these filters
pub filters: Vec<String>,
@@ -410,9 +413,6 @@ impl Config {
pub fn matches_arch(&self, arch: &str) -> bool {
self.target_cfg().arch == arch ||
- // Shorthand for convenience. The arch for
- // asmjs-unknown-emscripten is actually wasm32.
- (arch == "asmjs" && self.target.starts_with("asmjs")) ||
// Matching all the thumb variants as one can be convenient.
// (thumbv6m, thumbv7em, thumbv7m, etc.)
(arch == "thumb" && self.target.starts_with("thumb"))
@@ -479,6 +479,7 @@ impl TargetCfgs {
let mut targets: HashMap<String, TargetCfg> = serde_json::from_str(&rustc_output(
config,
&["--print=all-target-specs-json", "-Zunstable-options"],
+ Default::default(),
))
.unwrap();
@@ -491,16 +492,33 @@ impl TargetCfgs {
let mut all_families = HashSet::new();
let mut all_pointer_widths = HashSet::new();
- // Handle custom target specs, which are not included in `--print=all-target-specs-json`.
- if config.target.ends_with(".json") {
- targets.insert(
- config.target.clone(),
- serde_json::from_str(&rustc_output(
- config,
- &["--print=target-spec-json", "-Zunstable-options", "--target", &config.target],
- ))
- .unwrap(),
- );
+ // If current target is not included in the `--print=all-target-specs-json` output,
+ // we check whether it is a custom target from the user or a synthetic target from bootstrap.
+ if !targets.contains_key(&config.target) {
+ let mut envs: HashMap<String, String> = HashMap::new();
+
+ if let Ok(t) = std::env::var("RUST_TARGET_PATH") {
+ envs.insert("RUST_TARGET_PATH".into(), t);
+ }
+
+ // This returns false only when the target is neither a synthetic target
+ // nor a custom target from the user, indicating it is most likely invalid.
+ if config.target.ends_with(".json") || !envs.is_empty() {
+ targets.insert(
+ config.target.clone(),
+ serde_json::from_str(&rustc_output(
+ config,
+ &[
+ "--print=target-spec-json",
+ "-Zunstable-options",
+ "--target",
+ &config.target,
+ ],
+ envs,
+ ))
+ .unwrap(),
+ );
+ }
}
for (target, cfg) in targets.iter() {
@@ -545,7 +563,9 @@ impl TargetCfgs {
// code below extracts them from `--print=cfg`: make sure to only override fields that can
// actually be changed with `-C` flags.
for config in
- rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines()
+ rustc_output(config, &["--print=cfg", "--target", &config.target], Default::default())
+ .trim()
+ .lines()
{
let (name, value) = config
.split_once("=\"")
@@ -624,11 +644,12 @@ pub enum Endian {
Big,
}
-fn rustc_output(config: &Config, args: &[&str]) -> String {
+fn rustc_output(config: &Config, args: &[&str], envs: HashMap<String, String>) -> String {
let mut command = Command::new(&config.rustc_path);
add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
command.args(&config.target_rustcflags).args(args);
command.env("RUSTC_BOOTSTRAP", "1");
+ command.envs(envs);
let output = match command.output() {
Ok(output) => output,
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index d6516cff6..f85f9e674 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -632,7 +632,7 @@ fn iter_header_extra(
it(None, directive, 0);
}
- let comment = if testfile.extension().map(|e| e == "rs") == Some(true) { "//" } else { "#" };
+ let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//" } else { "#" };
let mut rdr = BufReader::new(rdr);
let mut ln = String::new();
diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs
index 77c2866b3..e2a04b7e5 100644
--- a/src/tools/compiletest/src/header/cfg.rs
+++ b/src/tools/compiletest/src/header/cfg.rs
@@ -146,8 +146,7 @@ pub(super) fn parse_cfg_name_directive<'a>(
}
// `wasm32-bare` is an alias to refer to just wasm32-unknown-unknown
- // (in contrast to `wasm32` which also matches non-bare targets like
- // asmjs-unknown-emscripten).
+ // (in contrast to `wasm32` which also matches non-bare targets)
condition! {
name: "wasm32-bare",
condition: config.target == "wasm32-unknown-unknown",
@@ -155,11 +154,6 @@ pub(super) fn parse_cfg_name_directive<'a>(
}
condition! {
- name: "asmjs",
- condition: config.target.starts_with("asmjs"),
- message: "when the architecture is asm.js",
- }
- condition! {
name: "thumb",
condition: config.target.starts_with("thumb"),
message: "when the architecture is part of the Thumb family"
@@ -196,8 +190,8 @@ pub(super) fn parse_cfg_name_directive<'a>(
}
condition! {
name: "debug",
- condition: cfg!(debug_assertions),
- message: "when building with debug assertions",
+ condition: config.with_debug_assertions,
+ message: "when running tests with `ignore-debug` header",
}
condition! {
name: config.debugger.as_ref().map(|d| d.to_str()),
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 85e745bed..295134c78 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -398,8 +398,6 @@ fn ignore_arch() {
("x86_64-unknown-linux-gnu", "x86_64"),
("i686-unknown-linux-gnu", "x86"),
("nvptx64-nvidia-cuda", "nvptx64"),
- ("asmjs-unknown-emscripten", "wasm32"),
- ("asmjs-unknown-emscripten", "asmjs"),
("thumbv7m-none-eabi", "thumb"),
];
for (target, arch) in archs {
@@ -492,9 +490,6 @@ fn wasm_special() {
("wasm32-unknown-unknown", "wasm32", true),
("wasm32-unknown-unknown", "wasm32-bare", true),
("wasm32-unknown-unknown", "wasm64", false),
- ("asmjs-unknown-emscripten", "emscripten", true),
- ("asmjs-unknown-emscripten", "wasm32", true),
- ("asmjs-unknown-emscripten", "wasm32-bare", false),
("wasm32-unknown-emscripten", "emscripten", true),
("wasm32-unknown-emscripten", "wasm32", true),
("wasm32-unknown-emscripten", "wasm32-bare", false),
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index bb09c03ef..5a80b9121 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -81,6 +81,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
)
.optopt("", "run", "whether to execute run-* tests", "auto | always | never")
.optflag("", "ignored", "run tests marked as ignored")
+ .optflag("", "with-debug-assertions", "whether to run tests with `ignore-debug` header")
.optmulti("", "skip", "skip tests matching SUBSTRING. Can be passed multiple times", "SUBSTRING")
.optflag("", "exact", "filters match exactly")
.optopt(
@@ -203,6 +204,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
let src_base = opt_path(matches, "src-base");
let run_ignored = matches.opt_present("ignored");
+ let with_debug_assertions = matches.opt_present("with-debug-assertions");
let mode = matches.opt_str("mode").unwrap().parse().expect("invalid mode");
let has_tidy = if mode == Mode::Rustdoc {
Command::new("tidy")
@@ -238,6 +240,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
suite: matches.opt_str("suite").unwrap(),
debugger: None,
run_ignored,
+ with_debug_assertions,
filters: matches.free.clone(),
skip: matches.opt_strs("skip"),
filter_exact: matches.opt_present("exact"),
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 63e8ba7c7..5d53a4d28 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -20,12 +20,11 @@ use regex::{Captures, Regex};
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
use std::borrow::Cow;
-use std::collections::hash_map::DefaultHasher;
use std::collections::{HashMap, HashSet};
use std::env;
use std::ffi::{OsStr, OsString};
use std::fs::{self, create_dir_all, File, OpenOptions};
-use std::hash::{Hash, Hasher};
+use std::hash::{DefaultHasher, Hash, Hasher};
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::iter;
@@ -475,14 +474,12 @@ impl<'test> TestCx<'test> {
self.fatal("missing --coverage-dump");
};
- let proc_res = self.compile_test_and_save_ir();
+ let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir();
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}
drop(proc_res);
- let llvm_ir_path = self.output_base_name().with_extension("ll");
-
let mut dump_command = Command::new(coverage_dump_path);
dump_command.arg(llvm_ir_path);
let proc_res = self.run_command_to_procres(&mut dump_command);
@@ -2546,10 +2543,10 @@ impl<'test> TestCx<'test> {
rustc.args(&["-Zpolonius"]);
}
Some(CompareMode::NextSolver) => {
- rustc.args(&["-Ztrait-solver=next"]);
+ rustc.args(&["-Znext-solver"]);
}
Some(CompareMode::NextSolverCoherence) => {
- rustc.args(&["-Ztrait-solver=next-coherence"]);
+ rustc.args(&["-Znext-solver=coherence"]);
}
Some(CompareMode::SplitDwarf) if self.config.target.contains("windows") => {
rustc.args(&["-Csplit-debuginfo=unpacked", "-Zunstable-options"]);
@@ -2786,10 +2783,54 @@ impl<'test> TestCx<'test> {
proc_res.fatal(None, || on_failure(*self));
}
+ fn get_output_file(&self, extension: &str) -> TargetLocation {
+ let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin"));
+ if thin_lto {
+ TargetLocation::ThisDirectory(self.output_base_dir())
+ } else {
+ // This works with both `--emit asm` (as default output name for the assembly)
+ // and `ptx-linker` because the latter can write output at requested location.
+ let output_path = self.output_base_name().with_extension(extension);
+ let output_file = TargetLocation::ThisFile(output_path.clone());
+ output_file
+ }
+ }
+
+ fn get_filecheck_file(&self, extension: &str) -> PathBuf {
+ let thin_lto = self.props.compile_flags.iter().any(|s| s.ends_with("lto=thin"));
+ if thin_lto {
+ let name = self.testpaths.file.file_stem().unwrap().to_str().unwrap();
+ let canonical_name = name.replace('-', "_");
+ let mut output_file = None;
+ for entry in self.output_base_dir().read_dir().unwrap() {
+ if let Ok(entry) = entry {
+ let entry_path = entry.path();
+ let entry_file = entry_path.file_name().unwrap().to_str().unwrap();
+ if entry_file.starts_with(&format!("{}.{}", name, canonical_name))
+ && entry_file.ends_with(extension)
+ {
+ assert!(
+ output_file.is_none(),
+ "thinlto doesn't support multiple cgu tests"
+ );
+ output_file = Some(entry_file.to_string());
+ }
+ }
+ }
+ if let Some(output_file) = output_file {
+ self.output_base_dir().join(output_file)
+ } else {
+ self.output_base_name().with_extension(extension)
+ }
+ } else {
+ self.output_base_name().with_extension(extension)
+ }
+ }
+
// codegen tests (using FileCheck)
- fn compile_test_and_save_ir(&self) -> ProcRes {
- let output_file = TargetLocation::ThisDirectory(self.output_base_dir());
+ fn compile_test_and_save_ir(&self) -> (ProcRes, PathBuf) {
+ let output_file = self.get_output_file("ll");
let input_file = &self.testpaths.file;
let rustc = self.make_compile_args(
input_file,
@@ -2800,15 +2841,13 @@ impl<'test> TestCx<'test> {
Vec::new(),
);
- self.compose_and_run_compiler(rustc, None)
+ let proc_res = self.compose_and_run_compiler(rustc, None);
+ let output_path = self.get_filecheck_file("ll");
+ (proc_res, output_path)
}
fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
- // This works with both `--emit asm` (as default output name for the assembly)
- // and `ptx-linker` because the latter can write output at requested location.
- let output_path = self.output_base_name().with_extension("s");
-
- let output_file = TargetLocation::ThisFile(output_path.clone());
+ let output_file = self.get_output_file("s");
let input_file = &self.testpaths.file;
let mut emit = Emit::None;
@@ -2838,7 +2877,9 @@ impl<'test> TestCx<'test> {
Vec::new(),
);
- (self.compose_and_run_compiler(rustc, None), output_path)
+ let proc_res = self.compose_and_run_compiler(rustc, None);
+ let output_path = self.get_filecheck_file("s");
+ (proc_res, output_path)
}
fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
@@ -2871,7 +2912,7 @@ impl<'test> TestCx<'test> {
self.fatal("missing --llvm-filecheck");
}
- let proc_res = self.compile_test_and_save_ir();
+ let (proc_res, output_path) = self.compile_test_and_save_ir();
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}
@@ -2879,8 +2920,6 @@ impl<'test> TestCx<'test> {
if let Some(PassMode::Build) = self.pass_mode() {
return;
}
-
- let output_path = self.output_base_name().with_extension("ll");
let proc_res = self.verify_with_filecheck(&output_path);
if !proc_res.status.success() {
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
@@ -3702,9 +3741,7 @@ impl<'test> TestCx<'test> {
let stderr_bits = format!("{}bit.stderr", self.config.get_pointer_width());
let (stderr_kind, stdout_kind) = match output_kind {
TestOutput::Compile => (
- {
- if self.props.stderr_per_bitwidth { &stderr_bits } else { UI_STDERR }
- },
+ { if self.props.stderr_per_bitwidth { &stderr_bits } else { UI_STDERR } },
UI_STDOUT,
),
TestOutput::Run => (UI_RUN_STDERR, UI_RUN_STDOUT),
@@ -4251,15 +4288,18 @@ impl<'test> TestCx<'test> {
let mut seen_allocs = indexmap::IndexSet::new();
// The alloc-id appears in pretty-printed allocations.
- let re = Regex::new(r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?─*╼").unwrap();
+ let re =
+ Regex::new(r"╾─*a(lloc)?([0-9]+)(\+0x[0-9]+)?(<imm>)?( \([0-9]+ ptr bytes\))?─*╼")
+ .unwrap();
normalized = re
.replace_all(&normalized, |caps: &Captures<'_>| {
// Renumber the captured index.
let index = caps.get(2).unwrap().as_str().to_string();
let (index, _) = seen_allocs.insert_full(index);
let offset = caps.get(3).map_or("", |c| c.as_str());
+ let imm = caps.get(4).map_or("", |c| c.as_str());
// Do not bother keeping it pretty, just make it deterministic.
- format!("╾ALLOC{index}{offset}╼")
+ format!("╾ALLOC{index}{offset}{imm}╼")
})
.into_owned();