Skip to content

Commit 501067c

Browse files
committed
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`
1 parent bd1d186 commit 501067c

File tree

3 files changed

+29
-37
lines changed

3 files changed

+29
-37
lines changed

compiler/rustc_middle/src/ty/layout.rs

+21-20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
66
use rustc_ast as ast;
77
use rustc_attr as attr;
88
use rustc_hir as hir;
9+
use rustc_hir::def_id::DefId;
910
use rustc_hir::lang_items::LangItem;
1011
use rustc_index::bit_set::BitSet;
1112
use rustc_index::vec::{Idx, IndexVec};
@@ -2762,14 +2763,22 @@ impl<'tcx> ty::Instance<'tcx> {
27622763
/// with `-Cpanic=abort` will look like they can't unwind when in fact they
27632764
/// might (from a foreign exception or similar).
27642765
#[inline]
2765-
pub fn fn_can_unwind<'tcx>(
2766-
tcx: TyCtxt<'tcx>,
2767-
codegen_fn_attr_flags: CodegenFnAttrFlags,
2768-
abi: SpecAbi,
2769-
) -> bool {
2770-
// Special attribute for functions which can't unwind.
2771-
if codegen_fn_attr_flags.contains(CodegenFnAttrFlags::NEVER_UNWIND) {
2772-
return false;
2766+
pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
2767+
if let Some(did) = fn_def_id {
2768+
// Special attribute for functions which can't unwind.
2769+
if tcx.codegen_fn_attrs(did).flags.contains(CodegenFnAttrFlags::NEVER_UNWIND) {
2770+
return false;
2771+
}
2772+
2773+
// With -Z panic-in-drop=abort, drop_in_place never unwinds.
2774+
//
2775+
// This is not part of `codegen_fn_attrs` as it can differ between crates
2776+
// and therefore cannot be computed in core.
2777+
if tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Abort {
2778+
if Some(did) == tcx.lang_items().drop_in_place_fn() {
2779+
return false;
2780+
}
2781+
}
27732782
}
27742783

27752784
// Otherwise if this isn't special then unwinding is generally determined by
@@ -2991,13 +3000,7 @@ fn fn_abi_of_fn_ptr<'tcx>(
29913000
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
29923001
let (param_env, (sig, extra_args)) = query.into_parts();
29933002

2994-
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
2995-
sig,
2996-
extra_args,
2997-
None,
2998-
CodegenFnAttrFlags::empty(),
2999-
false,
3000-
)
3003+
LayoutCx { tcx, param_env }.fn_abi_new_uncached(sig, extra_args, None, None, false)
30013004
}
30023005

30033006
fn fn_abi_of_instance<'tcx>(
@@ -3014,13 +3017,11 @@ fn fn_abi_of_instance<'tcx>(
30143017
None
30153018
};
30163019

3017-
let attrs = tcx.codegen_fn_attrs(instance.def_id()).flags;
3018-
30193020
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
30203021
sig,
30213022
extra_args,
30223023
caller_location,
3023-
attrs,
3024+
Some(instance.def_id()),
30243025
matches!(instance.def, ty::InstanceDef::Virtual(..)),
30253026
)
30263027
}
@@ -3033,7 +3034,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
30333034
sig: ty::PolyFnSig<'tcx>,
30343035
extra_args: &[Ty<'tcx>],
30353036
caller_location: Option<Ty<'tcx>>,
3036-
codegen_fn_attr_flags: CodegenFnAttrFlags,
3037+
fn_def_id: Option<DefId>,
30373038
// FIXME(eddyb) replace this with something typed, like an `enum`.
30383039
force_thin_self_ptr: bool,
30393040
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
@@ -3205,7 +3206,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
32053206
c_variadic: sig.c_variadic,
32063207
fixed_count: inputs.len(),
32073208
conv,
3208-
can_unwind: fn_can_unwind(self.tcx(), codegen_fn_attr_flags, sig.abi),
3209+
can_unwind: fn_can_unwind(self.tcx(), fn_def_id, sig.abi),
32093210
};
32103211
self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?;
32113212
debug!("fn_abi_new_uncached = {:?}", fn_abi);

compiler/rustc_mir_transform/src/abort_unwinding_calls.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::MirPass;
22
use rustc_hir::def::DefKind;
3-
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
43
use rustc_middle::mir::*;
54
use rustc_middle::ty::layout;
65
use rustc_middle::ty::{self, TyCtxt};
@@ -46,15 +45,14 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
4645
//
4746
// Here we test for this function itself whether its ABI allows
4847
// unwinding or not.
49-
let body_flags = tcx.codegen_fn_attrs(def_id).flags;
5048
let body_ty = tcx.type_of(def_id);
5149
let body_abi = match body_ty.kind() {
5250
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
5351
ty::Closure(..) => Abi::RustCall,
5452
ty::Generator(..) => Abi::Rust,
5553
_ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
5654
};
57-
let body_can_unwind = layout::fn_can_unwind(tcx, body_flags, body_abi);
55+
let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi);
5856

5957
// Look in this function body for any basic blocks which are terminated
6058
// with a function call, and whose function we're calling may unwind.
@@ -73,19 +71,19 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
7371
TerminatorKind::Call { func, .. } => {
7472
let ty = func.ty(body, tcx);
7573
let sig = ty.fn_sig(tcx);
76-
let flags = match ty.kind() {
77-
ty::FnPtr(_) => CodegenFnAttrFlags::empty(),
78-
ty::FnDef(def_id, _) => tcx.codegen_fn_attrs(*def_id).flags,
74+
let fn_def_id = match ty.kind() {
75+
ty::FnPtr(_) => None,
76+
&ty::FnDef(def_id, _) => Some(def_id),
7977
_ => span_bug!(span, "invalid callee of type {:?}", ty),
8078
};
81-
layout::fn_can_unwind(tcx, flags, sig.abi())
79+
layout::fn_can_unwind(tcx, fn_def_id, sig.abi())
8280
}
8381
TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => {
8482
tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Unwind
85-
&& layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust)
83+
&& layout::fn_can_unwind(tcx, None, Abi::Rust)
8684
}
8785
TerminatorKind::Assert { .. } | TerminatorKind::FalseUnwind { .. } => {
88-
layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust)
86+
layout::fn_can_unwind(tcx, None, Abi::Rust)
8987
}
9088
_ => continue,
9189
};

compiler/rustc_typeck/src/collect.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc_session::lint;
4545
use rustc_session::parse::feature_err;
4646
use rustc_span::symbol::{kw, sym, Ident, Symbol};
4747
use rustc_span::{Span, DUMMY_SP};
48-
use rustc_target::spec::{abi, PanicStrategy, SanitizerSet};
48+
use rustc_target::spec::{abi, SanitizerSet};
4949
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
5050
use std::iter;
5151

@@ -2726,13 +2726,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
27262726
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
27272727
}
27282728

2729-
// With -Z panic-in-drop=abort, drop_in_place never unwinds.
2730-
if tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Abort {
2731-
if Some(did.to_def_id()) == tcx.lang_items().drop_in_place_fn() {
2732-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND;
2733-
}
2734-
}
2735-
27362729
// The panic_no_unwind function called by TerminatorKind::Abort will never
27372730
// unwind. If the panic handler that it invokes unwind then it will simply
27382731
// call the panic handler again.

0 commit comments

Comments
 (0)