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`
This commit is contained in:
parent
bd1d18660b
commit
501067cb05
3 changed files with 29 additions and 37 deletions
|
@ -6,6 +6,7 @@ use crate::ty::{self, subst::SubstsRef, ReprOptions, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
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
|
/// with `-Cpanic=abort` will look like they can't unwind when in fact they
|
||||||
/// might (from a foreign exception or similar).
|
/// might (from a foreign exception or similar).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fn_can_unwind<'tcx>(
|
pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: SpecAbi) -> bool {
|
||||||
tcx: TyCtxt<'tcx>,
|
if let Some(did) = fn_def_id {
|
||||||
codegen_fn_attr_flags: CodegenFnAttrFlags,
|
// Special attribute for functions which can't unwind.
|
||||||
abi: SpecAbi,
|
if tcx.codegen_fn_attrs(did).flags.contains(CodegenFnAttrFlags::NEVER_UNWIND) {
|
||||||
) -> bool {
|
return false;
|
||||||
// Special attribute for functions which can't unwind.
|
}
|
||||||
if codegen_fn_attr_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
|
// 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>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||||
let (param_env, (sig, extra_args)) = query.into_parts();
|
let (param_env, (sig, extra_args)) = query.into_parts();
|
||||||
|
|
||||||
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
|
LayoutCx { tcx, param_env }.fn_abi_new_uncached(sig, extra_args, None, None, false)
|
||||||
sig,
|
|
||||||
extra_args,
|
|
||||||
None,
|
|
||||||
CodegenFnAttrFlags::empty(),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_abi_of_instance<'tcx>(
|
fn fn_abi_of_instance<'tcx>(
|
||||||
|
@ -3014,13 +3017,11 @@ fn fn_abi_of_instance<'tcx>(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let attrs = tcx.codegen_fn_attrs(instance.def_id()).flags;
|
|
||||||
|
|
||||||
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
|
LayoutCx { tcx, param_env }.fn_abi_new_uncached(
|
||||||
sig,
|
sig,
|
||||||
extra_args,
|
extra_args,
|
||||||
caller_location,
|
caller_location,
|
||||||
attrs,
|
Some(instance.def_id()),
|
||||||
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
matches!(instance.def, ty::InstanceDef::Virtual(..)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3033,7 +3034,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
extra_args: &[Ty<'tcx>],
|
extra_args: &[Ty<'tcx>],
|
||||||
caller_location: Option<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`.
|
// FIXME(eddyb) replace this with something typed, like an `enum`.
|
||||||
force_thin_self_ptr: bool,
|
force_thin_self_ptr: bool,
|
||||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> {
|
||||||
|
@ -3205,7 +3206,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
c_variadic: sig.c_variadic,
|
c_variadic: sig.c_variadic,
|
||||||
fixed_count: inputs.len(),
|
fixed_count: inputs.len(),
|
||||||
conv,
|
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)?;
|
self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?;
|
||||||
debug!("fn_abi_new_uncached = {:?}", fn_abi);
|
debug!("fn_abi_new_uncached = {:?}", fn_abi);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::layout;
|
use rustc_middle::ty::layout;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
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
|
// Here we test for this function itself whether its ABI allows
|
||||||
// unwinding or not.
|
// unwinding or not.
|
||||||
let body_flags = tcx.codegen_fn_attrs(def_id).flags;
|
|
||||||
let body_ty = tcx.type_of(def_id);
|
let body_ty = tcx.type_of(def_id);
|
||||||
let body_abi = match body_ty.kind() {
|
let body_abi = match body_ty.kind() {
|
||||||
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
|
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
|
||||||
|
@ -54,7 +52,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
|
||||||
ty::Generator(..) => Abi::Rust,
|
ty::Generator(..) => Abi::Rust,
|
||||||
_ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
|
_ => 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
|
// Look in this function body for any basic blocks which are terminated
|
||||||
// with a function call, and whose function we're calling may unwind.
|
// 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, .. } => {
|
TerminatorKind::Call { func, .. } => {
|
||||||
let ty = func.ty(body, tcx);
|
let ty = func.ty(body, tcx);
|
||||||
let sig = ty.fn_sig(tcx);
|
let sig = ty.fn_sig(tcx);
|
||||||
let flags = match ty.kind() {
|
let fn_def_id = match ty.kind() {
|
||||||
ty::FnPtr(_) => CodegenFnAttrFlags::empty(),
|
ty::FnPtr(_) => None,
|
||||||
ty::FnDef(def_id, _) => tcx.codegen_fn_attrs(*def_id).flags,
|
&ty::FnDef(def_id, _) => Some(def_id),
|
||||||
_ => span_bug!(span, "invalid callee of type {:?}", ty),
|
_ => 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 { .. } => {
|
TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } => {
|
||||||
tcx.sess.opts.debugging_opts.panic_in_drop == PanicStrategy::Unwind
|
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 { .. } => {
|
TerminatorKind::Assert { .. } | TerminatorKind::FalseUnwind { .. } => {
|
||||||
layout::fn_can_unwind(tcx, CodegenFnAttrFlags::empty(), Abi::Rust)
|
layout::fn_can_unwind(tcx, None, Abi::Rust)
|
||||||
}
|
}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@ use rustc_session::lint;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
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 rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
@ -2726,13 +2726,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
|
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
|
// The panic_no_unwind function called by TerminatorKind::Abort will never
|
||||||
// unwind. If the panic handler that it invokes unwind then it will simply
|
// unwind. If the panic handler that it invokes unwind then it will simply
|
||||||
// call the panic handler again.
|
// call the panic handler again.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue