diff options
| author | lcnr <rust@lcnr.de> | 2022-04-27 10:44:00 +0200 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2022-05-09 16:48:30 +0200 |
| commit | 501067cb05c7ed51b2142ed1b0eff968b4fe42e0 (patch) | |
| tree | a72719c7658189dafba35b7aea7d806915dab1de | |
| parent | bd1d18660b37f31ebc83bb8afd06b5d07df377c2 (diff) | |
| download | rust-501067cb05c7ed51b2142ed1b0eff968b4fe42e0.tar.gz rust-501067cb05c7ed51b2142ed1b0eff968b4fe42e0.zip | |
move `panic-in-drop=abort` check for `drop_in_place`
Whether `drop_in_place` can abort does depend on the `panic-in-drop` option while compiling the current crate, not `core`
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 41 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/abort_unwinding_calls.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/collect.rs | 9 |
3 files changed, 29 insertions, 37 deletions
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index cd4b23fca39..61f6dab1b21 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -6,6 +6,7 @@ use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable}; use rustc_ast as ast; use rustc_attr as attr; use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; @@ -2762,14 +2763,22 @@ impl<'tcx> ty::Instance<'tcx> { /// with `-Cpanic=abort` will look like they can't unwind when in fact they /// might (from a foreign exception or similar). #[inline] -pub fn fn_can_unwind<'tcx>( - tcx: TyCtxt<'tcx>, - codegen_fn_attr_flags: CodegenFnAttrFlags, - abi: SpecAbi, -) -> bool { - // Special attribute for functions which can't unwind. - if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::NEVER_UNWIND) { - return false; +pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool { + if let Some(did) = fn_def_id { + // Special attribute for functions which can't unwind. + if tcx.codegen_fn_attrs(did).flags.contains(CodegenFnAttrFlags::NEVER_UNWIND) { + 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.debugging_opts.panic_in_drop == PanicStrategy::Abort { + if Some(did) == tcx.lang_items().drop_in_place_fn() { + return false; + } + } } // Otherwise if this isn't special then unwinding is generally determined by @@ -2991,13 +3000,7 @@ fn fn_abi_of_fn_ptr<'tcx>( ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { let (param_env, (sig, extra_args)) = query.into_parts(); - LayoutCx { tcx, param_env }.fn_abi_new_uncached( - sig, - extra_args, - None, - CodegenFnAttrFlags::empty(), - false, - ) + LayoutCx { tcx, param_env }.fn_abi_new_uncached(sig, extra_args, None, None, false) } fn fn_abi_of_instance<'tcx>( @@ -3014,13 +3017,11 @@ fn fn_abi_of_instance<'tcx>( None }; - let attrs = tcx.codegen_fn_attrs(instance.def_id()).flags; - LayoutCx { tcx, param_env }.fn_abi_new_uncached( sig, extra_args, caller_location, - attrs, + Some(instance.def_id()), matches!(instance.def, ty::InstanceDef::Virtual(..)), ) } @@ -3033,7 +3034,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { sig: ty::PolyFnSig<'tcx>, extra_args: &[Ty<'tcx>], caller_location: Option<Ty<'tcx>>, - codegen_fn_attr_flags: CodegenFnAttrFlags, + fn_def_id: Option<DefId>, // FIXME(eddyb) replace this with something typed, like an `enum`. force_thin_self_ptr: bool, ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { @@ -3205,7 +3206,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { c_variadic: sig.c_variadic, fixed_count: inputs.len(), conv, - can_unwind: fn_can_unwind(self.tcx(), codegen_fn_attr_flags, sig.abi), + can_unwind: fn_can_unwind(self.tcx(), fn_def_id, sig.abi), }; self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?; debug!("fn_abi_new_uncached = {:?}", fn_abi); diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index 757dc093755..ade6555f4d2 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -1,6 +1,5 @@ use crate::MirPass; use rustc_hir::def::DefKind; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::*; use rustc_middle::ty::layout; use rustc_middle::ty::{self, TyCtxt}; @@ -46,7 +45,6 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { // // Here we test for this function itself whether its ABI allows // unwinding or not. - let body_flags = tcx.codegen_fn_attrs(def_id).flags; let body_ty = tcx.type_of(def_id); let body_abi = match body_ty.kind() { ty::FnDef(..) => body_ty.fn_sig(tcx).abi(), @@ -54,7 +52,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { ty::Generator(..) => Abi::Rust, _ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty), }; - let body_can_unwind = layout::fn_can_unwind(tcx, body_flags, body_abi); + let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi); // Look in this function body for any basic blocks which are terminated // with a function call, and whose function we're calling may unwind. @@ -73,19 +71,19 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { TerminatorKind::Call { func, .. } => { let ty = func.ty(body, tcx); let sig = ty.fn_sig(tcx); - let flags = match ty.kind() { - ty::FnPtr(_) => CodegenFnAttrFlags::empty(), - ty::FnDef(def_id, _) => tcx.codegen_fn_attrs(*def_id).flags, + let fn_def_id = match ty.kind() { + ty::FnPtr(_) => None, + &ty::FnDef(def_id, _) => Some(def_id), _ => span_bug!(span, "invalid callee of type {:?}", ty), }; - layout::fn_can_unwind(tcx, flags, sig.abi()) + layout::fn_can_unwind(tcx, fn_def_id, sig.abi()) } TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => { tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Unwind - && layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust) + && layout::fn_can_unwind(tcx, None, Abi::Rust) } TerminatorKind::Assert { .. } | TerminatorKind::FalseUnwind { .. } => { - layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust) + layout::fn_can_unwind(tcx, None, Abi::Rust) } _ => continue, }; diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 4c6a2ebd93b..b2aaaaa235c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -45,7 +45,7 @@ use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::spec::{abi, PanicStrategy, SanitizerSet}; +use rustc_target::spec::{abi, SanitizerSet}; use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; use std::iter; @@ -2726,13 +2726,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } - // With -Z panic-in-drop=abort, drop_in_place never unwinds. - if tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Abort { - if Some(did.to_def_id()) == tcx.lang_items().drop_in_place_fn() { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; - } - } - // The panic_no_unwind function called by TerminatorKind::Abort will never // unwind. If the panic handler that it invokes unwind then it will simply // call the panic handler again. |
