about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2022-04-27 10:44:00 +0200
committerlcnr <rust@lcnr.de>2022-05-09 16:48:30 +0200
commit501067cb05c7ed51b2142ed1b0eff968b4fe42e0 (patch)
treea72719c7658189dafba35b7aea7d806915dab1de
parentbd1d18660b37f31ebc83bb8afd06b5d07df377c2 (diff)
downloadrust-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.rs41
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs16
-rw-r--r--compiler/rustc_typeck/src/collect.rs9
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.