Skip to content

Commit a7bb867

Browse files
committed
Add panic=immediate-abort
1 parent 1ed3cd7 commit a7bb867

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+304
-117
lines changed

compiler/rustc_builtin_macros/src/test_harness.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ pub fn inject(
6464

6565
if sess.is_test_crate() {
6666
let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) {
67-
(PanicStrategy::Abort, true) => PanicStrategy::Abort,
68-
(PanicStrategy::Abort, false) => {
67+
(PanicStrategy::Abort | PanicStrategy::ImmediateAbort, true) => PanicStrategy::Abort,
68+
(PanicStrategy::Abort | PanicStrategy::ImmediateAbort, false) => {
6969
if panic_strategy == platform_panic_strategy {
7070
// Silently allow compiling with panic=abort on these platforms,
7171
// but with old behavior (abort if a test fails).
@@ -290,7 +290,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box<ast::Item> {
290290

291291
let runner_name = match cx.panic_strategy {
292292
PanicStrategy::Unwind => "test_main_static",
293-
PanicStrategy::Abort => "test_main_static_abort",
293+
PanicStrategy::Abort | PanicStrategy::ImmediateAbort => "test_main_static_abort",
294294
};
295295

296296
// test::test_main_static(...)

compiler/rustc_metadata/messages.ftl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ metadata_full_metadata_not_found =
9898
metadata_global_alloc_required =
9999
no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
100100
101+
metadata_incompatible_with_immediate_abort =
102+
the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort`
103+
104+
metadata_incompatible_with_immediate_abort_core =
105+
the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`
106+
.help = consider building the standard library from source with `cargo build -Zbuild-std`
107+
101108
metadata_incompatible_panic_in_drop_strategy =
102109
the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
103110

compiler/rustc_metadata/src/creader.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,10 @@ impl CStore {
10271027
let name = match desired_strategy {
10281028
PanicStrategy::Unwind => sym::panic_unwind,
10291029
PanicStrategy::Abort => sym::panic_abort,
1030+
PanicStrategy::ImmediateAbort => {
1031+
// Immediate-aborting panics don't use a runtime.
1032+
return;
1033+
}
10301034
};
10311035
info!("panic runtime not found -- loading {}", name);
10321036

compiler/rustc_metadata/src/dependency_format.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ use rustc_session::config::CrateType;
6161
use rustc_session::cstore::CrateDepKind;
6262
use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
6363
use rustc_span::sym;
64+
use rustc_target::spec::PanicStrategy;
6465
use tracing::info;
6566

6667
use crate::creader::CStore;
6768
use crate::errors::{
68-
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
69+
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy,
70+
IncompatibleWithImmediateAbort, IncompatibleWithImmediateAbortCore, LibRequired,
6971
NonStaticCrateDep, RequiredPanicStrategy, RlibRequired, RustcDriverHelp, RustcLibRequired,
7072
TwoPanicRuntimes,
7173
};
@@ -405,6 +407,33 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
405407
if list.is_empty() {
406408
return;
407409
}
410+
let desired_strategy = sess.panic_strategy();
411+
412+
// If we are panic=immediate-abort, make sure everything in the dependency tree has also been
413+
// compiled with immediate-abort.
414+
if desired_strategy == PanicStrategy::ImmediateAbort {
415+
let mut invalid_crates = Vec::new();
416+
for (cnum, linkage) in list.iter_enumerated() {
417+
if let Linkage::NotLinked = *linkage {
418+
continue;
419+
}
420+
let found_strategy = tcx.required_panic_strategy(cnum);
421+
if found_strategy != Some(PanicStrategy::ImmediateAbort) {
422+
invalid_crates.push(cnum);
423+
// If core is incompatible, it's very likely that we'd emit an error for every
424+
// sysroot crate, so instead of doing that emit a single fatal error that suggests
425+
// using build-std.
426+
if tcx.crate_name(cnum) == sym::core {
427+
sess.dcx().emit_fatal(IncompatibleWithImmediateAbortCore);
428+
}
429+
}
430+
}
431+
for cnum in invalid_crates {
432+
sess.dcx()
433+
.emit_err(IncompatibleWithImmediateAbort { crate_name: tcx.crate_name(cnum) });
434+
}
435+
}
436+
408437
let mut panic_runtime = None;
409438
for (cnum, linkage) in list.iter_enumerated() {
410439
if let Linkage::NotLinked = *linkage {
@@ -430,8 +459,6 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
430459
// only one, but we perform validation here that all the panic strategy
431460
// compilation modes for the whole DAG are valid.
432461
if let Some((runtime_cnum, found_strategy)) = panic_runtime {
433-
let desired_strategy = sess.panic_strategy();
434-
435462
// First up, validate that our selected panic runtime is indeed exactly
436463
// our same strategy.
437464
if found_strategy != desired_strategy {

compiler/rustc_metadata/src/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ pub struct RequiredPanicStrategy {
7575
pub desired_strategy: PanicStrategy,
7676
}
7777

78+
#[derive(Diagnostic)]
79+
#[diag(metadata_incompatible_with_immediate_abort)]
80+
pub struct IncompatibleWithImmediateAbort {
81+
pub crate_name: Symbol,
82+
}
83+
84+
#[derive(Diagnostic)]
85+
#[diag(metadata_incompatible_with_immediate_abort_core)]
86+
pub struct IncompatibleWithImmediateAbortCore;
87+
7888
#[derive(Diagnostic)]
7989
#[diag(metadata_incompatible_panic_in_drop_strategy)]
8090
pub struct IncompatiblePanicInDropStrategy {

compiler/rustc_middle/src/middle/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,6 @@ pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
9898
lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
9999
}
100100
PanicStrategy::Unwind => true,
101+
PanicStrategy::ImmediateAbort => false,
101102
}
102103
}

compiler/rustc_mir_transform/src/ffi_unwind_calls.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,15 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
101101
}
102102

103103
fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrategy> {
104+
let local_strategy = tcx.sess.panic_strategy();
105+
104106
if tcx.is_panic_runtime(LOCAL_CRATE) {
105-
return Some(tcx.sess.panic_strategy());
107+
return Some(local_strategy);
106108
}
107109

108-
if tcx.sess.panic_strategy() == PanicStrategy::Abort {
109-
return Some(PanicStrategy::Abort);
110+
match local_strategy {
111+
PanicStrategy::Abort | PanicStrategy::ImmediateAbort => return Some(local_strategy),
112+
_ => {}
110113
}
111114

112115
for def_id in tcx.hir_body_owners() {

compiler/rustc_session/src/config.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ use rustc_span::{
2929
SourceFileHashAlgorithm, Symbol, sym,
3030
};
3131
use rustc_target::spec::{
32-
FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
32+
FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
33+
Target, TargetTuple,
3334
};
3435
use tracing::debug;
3536

@@ -2791,6 +2792,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
27912792
}
27922793
}
27932794

2795+
if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
2796+
early_dcx.early_fatal(
2797+
"`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
2798+
)
2799+
}
2800+
27942801
let crate_name = matches.opt_str("crate-name");
27952802
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
27962803
// Parse any `-l` flags, which link to native libraries.

compiler/rustc_session/src/config/cfg.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ pub(crate) fn disallow_cfgs(sess: &Session, user_cfgs: &Cfg) {
125125
None | Some(_),
126126
) => disallow(cfg, "-Z sanitizer=cfi"),
127127
(sym::proc_macro, None) => disallow(cfg, "--crate-type proc-macro"),
128-
(sym::panic, Some(sym::abort | sym::unwind)) => disallow(cfg, "-C panic"),
128+
(sym::panic, Some(sym::abort | sym::unwind | sym::immediate_abort)) => {
129+
disallow(cfg, "-C panic")
130+
}
129131
(sym::target_feature, Some(_)) => disallow(cfg, "-C target-feature"),
130132
(sym::unix, None)
131133
| (sym::windows, None)

compiler/rustc_session/src/options.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ mod desc {
802802
pub(crate) const parse_threads: &str = parse_number;
803803
pub(crate) const parse_time_passes_format: &str = "`text` (default) or `json`";
804804
pub(crate) const parse_passes: &str = "a space-separated list of passes, or `all`";
805-
pub(crate) const parse_panic_strategy: &str = "either `unwind` or `abort`";
805+
pub(crate) const parse_panic_strategy: &str = "either `unwind`, `abort`, or `immediate-abort`";
806806
pub(crate) const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`";
807807
pub(crate) const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)";
808808
pub(crate) const parse_opt_panic_strategy: &str = parse_panic_strategy;
@@ -1165,6 +1165,7 @@ pub mod parse {
11651165
match v {
11661166
Some("unwind") => *slot = Some(PanicStrategy::Unwind),
11671167
Some("abort") => *slot = Some(PanicStrategy::Abort),
1168+
Some("immediate-abort") => *slot = Some(PanicStrategy::ImmediateAbort),
11681169
_ => return false,
11691170
}
11701171
true
@@ -1174,6 +1175,7 @@ pub mod parse {
11741175
match v {
11751176
Some("unwind") => *slot = PanicStrategy::Unwind,
11761177
Some("abort") => *slot = PanicStrategy::Abort,
1178+
Some("immediate-abort") => *slot = PanicStrategy::ImmediateAbort,
11771179
_ => return false,
11781180
}
11791181
true

0 commit comments

Comments
 (0)