Skip to content

Commit 9de3c29

Browse files
committed
add support for blessing panic=abort mir-opt tests
1 parent 9ec370d commit 9de3c29

File tree

4 files changed

+107
-3
lines changed

4 files changed

+107
-3
lines changed

src/bootstrap/config.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ impl std::str::FromStr for RustcLto {
429429
pub struct TargetSelection {
430430
pub triple: Interned<String>,
431431
file: Option<Interned<String>>,
432+
synthetic: bool,
432433
}
433434

434435
/// Newtype over `Vec<TargetSelection>` so we can implement custom parsing logic
@@ -460,7 +461,15 @@ impl TargetSelection {
460461
let triple = INTERNER.intern_str(triple);
461462
let file = file.map(|f| INTERNER.intern_str(f));
462463

463-
Self { triple, file }
464+
Self { triple, file, synthetic: false }
465+
}
466+
467+
pub fn create_synthetic(triple: &str, file: &str) -> Self {
468+
Self {
469+
triple: INTERNER.intern_str(triple),
470+
file: Some(INTERNER.intern_str(file)),
471+
synthetic: true,
472+
}
464473
}
465474

466475
pub fn rustc_target_arg(&self) -> &str {
@@ -478,6 +487,11 @@ impl TargetSelection {
478487
pub fn ends_with(&self, needle: &str) -> bool {
479488
self.triple.ends_with(needle)
480489
}
490+
491+
// See src/bootstrap/synthetic_targets.rs
492+
pub fn is_synthetic(&self) -> bool {
493+
self.synthetic
494+
}
481495
}
482496

483497
impl fmt::Display for TargetSelection {

src/bootstrap/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ mod run;
6161
mod sanity;
6262
mod setup;
6363
mod suggest;
64+
mod synthetic_targets;
6465
mod tarball;
6566
mod test;
6667
mod tool;

src/bootstrap/synthetic_targets.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//! In some cases, parts of bootstrap need to change part of a target spec just for one or a few
2+
//! steps. Adding these targets to rustc proper would "leak" this implementation detail of
3+
//! bootstrap, and would make it more complex to apply additional changes if the need arises.
4+
//!
5+
//! To address that problem, this module implements support for "synthetic targets". Synthetic
6+
//! targets are custom target specs generated using builtin target specs as their base. You can use
7+
//! one of the target specs already defined in this module, or create new ones by adding a new step
8+
//! that calls create_synthetic_target.
9+
10+
use crate::builder::{Builder, ShouldRun, Step};
11+
use crate::config::TargetSelection;
12+
use crate::Compiler;
13+
use std::process::{Command, Stdio};
14+
15+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
16+
pub(crate) struct MirOptPanicAbortSyntheticTarget {
17+
pub(crate) compiler: Compiler,
18+
pub(crate) base: TargetSelection,
19+
}
20+
21+
impl Step for MirOptPanicAbortSyntheticTarget {
22+
type Output = TargetSelection;
23+
const DEFAULT: bool = true;
24+
const ONLY_HOSTS: bool = false;
25+
26+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
27+
run.never()
28+
}
29+
30+
fn run(self, builder: &Builder<'_>) -> Self::Output {
31+
create_synthetic_target(builder, self.compiler, "miropt-abort", self.base, |spec| {
32+
spec.insert("panic-strategy".into(), "abort".into());
33+
})
34+
}
35+
}
36+
37+
fn create_synthetic_target(
38+
builder: &Builder<'_>,
39+
compiler: Compiler,
40+
suffix: &str,
41+
base: TargetSelection,
42+
customize: impl FnOnce(&mut serde_json::Map<String, serde_json::Value>),
43+
) -> TargetSelection {
44+
if base.contains("synthetic") {
45+
// This check is not strictly needed, but nothing currently needs recursive synthetic
46+
// targets. If the need arises, removing this in the future *SHOULD* be safe.
47+
panic!("cannot create synthetic targets with other synthetic targets as their base");
48+
}
49+
50+
let name = format!("{base}-synthetic-{suffix}");
51+
let path = builder.out.join("synthetic-target-specs").join(format!("{name}.json"));
52+
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
53+
54+
if builder.config.dry_run() {
55+
std::fs::write(&path, b"dry run\n").unwrap();
56+
return TargetSelection::create_synthetic(&name, path.to_str().unwrap());
57+
}
58+
59+
let mut cmd = Command::new(builder.rustc(compiler));
60+
cmd.arg("--target").arg(base.rustc_target_arg());
61+
cmd.args(["-Zunstable-options", "--print", "target-spec-json"]);
62+
cmd.stdout(Stdio::piped());
63+
64+
let output = cmd.spawn().unwrap().wait_with_output().unwrap();
65+
if !output.status.success() {
66+
panic!("failed to gather the target spec for {base}");
67+
}
68+
69+
let mut spec: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
70+
let spec_map = spec.as_object_mut().unwrap();
71+
72+
// The `is-builtin` attribute of a spec needs to be removed, otherwise rustc will complain.
73+
spec_map.remove("is-builtin");
74+
75+
customize(spec_map);
76+
77+
std::fs::write(&path, &serde_json::to_vec_pretty(&spec).unwrap()).unwrap();
78+
let target = TargetSelection::create_synthetic(&name, path.to_str().unwrap());
79+
crate::cc_detect::find_target(builder, target);
80+
81+
target
82+
}

src/bootstrap/test.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::doc::DocumentationFormat;
2323
use crate::flags::Subcommand;
2424
use crate::llvm;
2525
use crate::render_tests::add_flags_and_try_run_tests;
26+
use crate::synthetic_targets::MirOptPanicAbortSyntheticTarget;
2627
use crate::tool::{self, SourceType, Tool};
2728
use crate::toolstate::ToolState;
2829
use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t, up_to_date};
@@ -1347,8 +1348,8 @@ impl Step for MirOpt {
13471348
};
13481349

13491350
// We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants
1350-
// (32bit vs 64bit), and all of them needs to be blessed. When blessing, we try best-effort
1351-
// to also bless the other variants, to aid developers.
1351+
// (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed.
1352+
// When blessing, we try best-effort to also bless the other variants, to aid developers.
13521353
if builder.config.cmd.bless() {
13531354
let targets = MIR_OPT_BLESS_TARGET_MAPPING
13541355
.iter()
@@ -1385,6 +1386,12 @@ You can add that mapping by changing MIR_OPT_BLESS_TARGET_MAPPING in src/bootstr
13851386

13861387
for target in targets {
13871388
run(target);
1389+
1390+
let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget {
1391+
compiler: self.compiler,
1392+
base: target,
1393+
});
1394+
run(panic_abort_target);
13881395
}
13891396
} else {
13901397
run(self.target);

0 commit comments

Comments
 (0)