Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ pub fn inject(

if sess.is_test_crate() {
let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) {
(PanicStrategy::Abort, true) => PanicStrategy::Abort,
(PanicStrategy::Abort, false) => {
(PanicStrategy::Abort | PanicStrategy::ImmediateAbort, true) => panic_strategy,
(PanicStrategy::Abort | PanicStrategy::ImmediateAbort, false) => {
if panic_strategy == platform_panic_strategy {
// Silently allow compiling with panic=abort on these platforms,
// but with old behavior (abort if a test fails).
Expand Down Expand Up @@ -287,10 +287,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box<ast::Item> {
let ecx = &cx.ext_cx;
let test_ident = Ident::new(sym::test, sp);

let runner_name = match cx.panic_strategy {
PanicStrategy::Unwind => "test_main_static",
PanicStrategy::Abort => "test_main_static_abort",
};
let runner_name =
if cx.panic_strategy.unwinds() { "test_main_static" } else { "test_main_static_abort" };

// test::test_main_static(...)
let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::DebugInfo;
use rustc_span::Symbol;
use rustc_target::spec::RelocModel;
#[cfg(feature = "master")]
use rustc_target::spec::SymbolVisibility;
use rustc_target::spec::{PanicStrategy, RelocModel};

use crate::builder::Builder;
use crate::context::CodegenCx;
Expand Down Expand Up @@ -101,7 +101,7 @@ pub fn compile_codegen_unit(
// Instantiate monomorphizations without filling out definitions yet...
let context = new_context(tcx);

if tcx.sess.panic_strategy() == PanicStrategy::Unwind {
if tcx.sess.panic_strategy().unwinds() {
context.add_command_line_option("-fexceptions");
context.add_driver_option("-fexceptions");
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::{ArgAbi, PassMode};
use rustc_target::spec::PanicStrategy;

#[cfg(feature = "master")]
use crate::abi::FnAbiGccExt;
Expand Down Expand Up @@ -1334,7 +1333,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
_catch_func: RValue<'gcc>,
dest: PlaceRef<'tcx, RValue<'gcc>>,
) {
if bx.sess().panic_strategy() == PanicStrategy::Abort {
if !bx.sess().panic_strategy().unwinds() {
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
// Return 0 unconditionally from the intrinsic call;
// we can never unwind.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use rustc_middle::{bug, span_bug};
use rustc_span::{Span, Symbol, sym};
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
use rustc_target::callconv::PassMode;
use rustc_target::spec::PanicStrategy;
use tracing::debug;

use crate::abi::FnAbiLlvmExt;
Expand Down Expand Up @@ -674,7 +673,7 @@ fn catch_unwind_intrinsic<'ll, 'tcx>(
catch_func: &'ll Value,
dest: PlaceRef<'tcx, &'ll Value>,
) {
if bx.sess().panic_strategy() == PanicStrategy::Abort {
if !bx.sess().panic_strategy().unwinds() {
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
bx.call(try_func_ty, None, None, try_func, &[data], None, None);
// Return 0 unconditionally from the intrinsic call;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ unsafe fn configure_llvm(sess: &Session) {

if sess.target.os == "emscripten"
&& !sess.opts.unstable_opts.emscripten_wasm_eh
&& sess.panic_strategy() == PanicStrategy::Unwind
&& sess.panic_strategy().unwinds()
{
add("-enable-emscripten-cxx-exceptions", false);
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ use rustc_span::Symbol;
use rustc_target::spec::crt_objects::CrtObjects;
use rustc_target::spec::{
BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault,
LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel,
SanitizerSet, SplitDebuginfo,
LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, RelocModel, RelroLevel, SanitizerSet,
SplitDebuginfo,
};
use tracing::{debug, info, warn};

Expand Down Expand Up @@ -2512,10 +2512,10 @@ fn add_order_independent_options(
if sess.target.os == "emscripten" {
cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh {
"-fwasm-exceptions"
} else if sess.panic_strategy() == PanicStrategy::Abort {
"-sDISABLE_EXCEPTION_CATCHING=1"
} else {
} else if sess.panic_strategy().unwinds() {
"-sDISABLE_EXCEPTION_CATCHING=0"
} else {
"-sDISABLE_EXCEPTION_CATCHING=1"
});
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ interface_out_dir_error =
failed to find or create the directory specified by `--out-dir`

interface_proc_macro_crate_panic_abort =
building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic
building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

panic=abort would still give an error message. panic=immediate-abort would silently crash the compiler, which is much worse. Maybe trying to do the latter should be a hard error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any crash is silent; at least on Linux the crash we produce here is at least as loud as an OOM.

The warning here was added relatively recently because some embedded developers who have -Cpanic=abort set in their environment also were confused when their proc-macros aborted instead of surfacing the panic message through the compiler.

What you are suggesting would hard-break that embedded dev workflow, which seems like a bad tradeoff for me. I expect that most people setting enabling -Cpanic=immediate-abort in their environment are not also debugging proc macro panics and would just find the error annoying.


interface_temps_dir_error =
failed to find or create the directory specified by `--temps-dir`
3 changes: 1 addition & 2 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ use rustc_span::{
DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, SourceFileHash, SourceFileHashAlgorithm, Span,
Symbol, sym,
};
use rustc_target::spec::PanicStrategy;
use rustc_trait_selection::{solve, traits};
use tracing::{info, instrument};

Expand Down Expand Up @@ -282,7 +281,7 @@ fn configure_and_expand(
feature_err(sess, sym::export_stable, DUMMY_SP, "`sdylib` crate type is unstable").emit();
}

if is_proc_macro_crate && sess.panic_strategy() == PanicStrategy::Abort {
if is_proc_macro_crate && !sess.panic_strategy().unwinds() {
sess.dcx().emit_warn(errors::ProcMacroCratePanicAbort);
}

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_metadata/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ metadata_full_metadata_not_found =
metadata_global_alloc_required =
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

metadata_incompatible_with_immediate_abort =
the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort`

metadata_incompatible_with_immediate_abort_core =
the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`
.help = consider building the standard library from source with `cargo build -Zbuild-std`

metadata_incompatible_panic_in_drop_strategy =
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}`

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,10 @@ impl CStore {
let name = match desired_strategy {
PanicStrategy::Unwind => sym::panic_unwind,
PanicStrategy::Abort => sym::panic_abort,
PanicStrategy::ImmediateAbort => {
// Immediate-aborting panics don't use a runtime.
return;
}
};
info!("panic runtime not found -- loading {}", name);

Expand Down
47 changes: 36 additions & 11 deletions compiler/rustc_metadata/src/dependency_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ use rustc_session::config::CrateType;
use rustc_session::cstore::CrateDepKind;
use rustc_session::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
use rustc_span::sym;
use rustc_target::spec::PanicStrategy;
use tracing::info;

use crate::creader::CStore;
use crate::errors::{
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy,
IncompatibleWithImmediateAbort, IncompatibleWithImmediateAbortCore, LibRequired,
NonStaticCrateDep, RequiredPanicStrategy, RlibRequired, RustcDriverHelp, RustcLibRequired,
TwoPanicRuntimes,
};
Expand Down Expand Up @@ -402,15 +404,43 @@ fn activate_injected_dep(
/// there's only going to be one panic runtime in the output.
fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
let sess = &tcx.sess;
let list: Vec<_> = list
.iter_enumerated()
.filter_map(
|(cnum, linkage)| if *linkage == Linkage::NotLinked { None } else { Some(cnum) },
)
.collect();
if list.is_empty() {
return;
}
let mut panic_runtime = None;
for (cnum, linkage) in list.iter_enumerated() {
if let Linkage::NotLinked = *linkage {
continue;
let desired_strategy = sess.panic_strategy();

// If we are panic=immediate-abort, make sure everything in the dependency tree has also been
// compiled with immediate-abort.
if list
.iter()
.any(|cnum| tcx.required_panic_strategy(*cnum) == Some(PanicStrategy::ImmediateAbort))
{
let mut invalid_crates = Vec::new();
for cnum in list.iter().copied() {
if tcx.required_panic_strategy(cnum) != Some(PanicStrategy::ImmediateAbort) {
invalid_crates.push(cnum);
// If core is incompatible, it's very likely that we'd emit an error for every
// sysroot crate, so instead of doing that emit a single fatal error that suggests
// using build-std.
if tcx.crate_name(cnum) == sym::core {
sess.dcx().emit_fatal(IncompatibleWithImmediateAbortCore);
}
}
}
for cnum in invalid_crates {
sess.dcx()
.emit_err(IncompatibleWithImmediateAbort { crate_name: tcx.crate_name(cnum) });
}
}

let mut panic_runtime = None;
for cnum in list.iter().copied() {
if tcx.is_panic_runtime(cnum) {
if let Some((prev, _)) = panic_runtime {
let prev_name = tcx.crate_name(prev);
Expand All @@ -430,8 +460,6 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
// only one, but we perform validation here that all the panic strategy
// compilation modes for the whole DAG are valid.
if let Some((runtime_cnum, found_strategy)) = panic_runtime {
let desired_strategy = sess.panic_strategy();

// First up, validate that our selected panic runtime is indeed exactly
// our same strategy.
if found_strategy != desired_strategy {
Expand All @@ -445,10 +473,7 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
// strategy. If the dep isn't linked, we ignore it, and if our strategy
// is abort then it's compatible with everything. Otherwise all crates'
// panic strategy must match our own.
for (cnum, linkage) in list.iter_enumerated() {
if let Linkage::NotLinked = *linkage {
continue;
}
for cnum in list.iter().copied() {
if cnum == runtime_cnum || tcx.is_compiler_builtins(cnum) {
continue;
}
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_metadata/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ pub struct RequiredPanicStrategy {
pub desired_strategy: PanicStrategy,
}

#[derive(Diagnostic)]
#[diag(metadata_incompatible_with_immediate_abort)]
pub struct IncompatibleWithImmediateAbort {
pub crate_name: Symbol,
}

#[derive(Diagnostic)]
#[diag(metadata_incompatible_with_immediate_abort_core)]
pub struct IncompatibleWithImmediateAbortCore;

#[derive(Diagnostic)]
#[diag(metadata_incompatible_panic_in_drop_strategy)]
pub struct IncompatiblePanicInDropStrategy {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@ pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
}
PanicStrategy::Unwind => true,
PanicStrategy::ImmediateAbort => false,
}
}
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable, extension};
use rustc_session::config::OptLevel;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
use rustc_target::callconv::FnAbi;
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, PanicStrategy, Target, X86Abi};
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, X86Abi};
use tracing::debug;
use {rustc_abi as abi, rustc_hir as hir};

Expand Down Expand Up @@ -1198,15 +1198,15 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
//
// Note that this is true regardless ABI specified on the function -- a `extern "C-unwind"`
// function defined in Rust is also required to abort.
if tcx.sess.panic_strategy() == PanicStrategy::Abort && !tcx.is_foreign_item(did) {
if !tcx.sess.panic_strategy().unwinds() && !tcx.is_foreign_item(did) {
return false;
}

// With -Z panic-in-drop=abort, drop_in_place never unwinds.
//
// This is not part of `codegen_fn_attrs` as it can differ between crates
// and therefore cannot be computed in core.
if tcx.sess.opts.unstable_opts.panic_in_drop == PanicStrategy::Abort
if !tcx.sess.opts.unstable_opts.panic_in_drop.unwinds()
&& tcx.is_lang_item(did, LangItem::DropInPlace)
{
return false;
Expand Down Expand Up @@ -1245,7 +1245,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
| RiscvInterruptS
| RustInvalid
| Unadjusted => false,
Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
Rust | RustCall | RustCold => tcx.sess.panic_strategy().unwinds(),
}
}

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_transform/src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::source_map::dummy_spanned;
use rustc_span::symbol::sym;
use rustc_span::{DUMMY_SP, Span};
use rustc_target::spec::PanicStrategy;
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::TyCtxtInferExt as _;
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
Expand Down Expand Up @@ -1149,7 +1148,7 @@ fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, typing_env: ty::Typing

fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool {
// Nothing can unwind when landing pads are off.
if tcx.sess.panic_strategy() == PanicStrategy::Abort {
if !tcx.sess.panic_strategy().unwinds() {
return false;
}

Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,15 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
}

fn required_panic_strategy(tcx: TyCtxt<'_>, _: LocalCrate) -> Option<PanicStrategy> {
let local_strategy = tcx.sess.panic_strategy();

if tcx.is_panic_runtime(LOCAL_CRATE) {
return Some(tcx.sess.panic_strategy());
return Some(local_strategy);
}

if tcx.sess.panic_strategy() == PanicStrategy::Abort {
return Some(PanicStrategy::Abort);
match local_strategy {
PanicStrategy::Abort | PanicStrategy::ImmediateAbort => return Some(local_strategy),
_ => {}
}

for def_id in tcx.hir_body_owners() {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use rustc_target::spec::PanicStrategy;
use tracing::debug;

use crate::patch::MirPatch;
Expand All @@ -13,7 +12,7 @@ pub(super) struct RemoveNoopLandingPads;

impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.panic_strategy() != PanicStrategy::Abort
sess.panic_strategy().unwinds()
}

fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ use rustc_span::{
SourceFileHashAlgorithm, Symbol, sym,
};
use rustc_target::spec::{
FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
Target, TargetTuple,
};
use tracing::debug;

Expand Down Expand Up @@ -2799,6 +2800,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
}
}

if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
early_dcx.early_fatal(
"`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
)
}

let crate_name = matches.opt_str("crate-name");
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
// Parse any `-l` flags, which link to native libraries.
Expand Down
Loading
Loading