Don't infer unwinding of virtual calls based on the function attributes
This commit is contained in:
parent
8089fce101
commit
fbe0075a86
2 changed files with 32 additions and 6 deletions
|
@ -543,11 +543,13 @@ fn fn_abi_new_uncached<'tcx>(
|
||||||
instance: Option<ty::Instance<'tcx>>,
|
instance: Option<ty::Instance<'tcx>>,
|
||||||
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, &'tcx FnAbiError<'tcx>> {
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
let (caller_location, fn_def_id, is_virtual_call) = if let Some(instance) = instance {
|
let (caller_location, determined_fn_def_id, is_virtual_call) = if let Some(instance) = instance
|
||||||
|
{
|
||||||
|
let is_virtual_call = matches!(instance.def, ty::InstanceKind::Virtual(..));
|
||||||
(
|
(
|
||||||
instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()),
|
instance.def.requires_caller_location(tcx).then(|| tcx.caller_location_ty()),
|
||||||
Some(instance.def_id()),
|
if is_virtual_call { None } else { Some(instance.def_id()) },
|
||||||
matches!(instance.def, ty::InstanceKind::Virtual(..)),
|
is_virtual_call,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(None, None, false)
|
(None, None, false)
|
||||||
|
@ -577,7 +579,7 @@ fn fn_abi_new_uncached<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_drop_in_place =
|
let is_drop_in_place =
|
||||||
fn_def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::DropInPlace));
|
determined_fn_def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::DropInPlace));
|
||||||
|
|
||||||
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, &'tcx FnAbiError<'tcx>> {
|
let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, &'tcx FnAbiError<'tcx>> {
|
||||||
let span = tracing::debug_span!("arg_of");
|
let span = tracing::debug_span!("arg_of");
|
||||||
|
@ -633,7 +635,12 @@ fn fn_abi_new_uncached<'tcx>(
|
||||||
c_variadic: sig.c_variadic,
|
c_variadic: sig.c_variadic,
|
||||||
fixed_count: inputs.len() as u32,
|
fixed_count: inputs.len() as u32,
|
||||||
conv,
|
conv,
|
||||||
can_unwind: fn_can_unwind(cx.tcx(), fn_def_id, sig.abi),
|
can_unwind: fn_can_unwind(
|
||||||
|
tcx,
|
||||||
|
// Since `#[rustc_nounwind]` can change unwinding, we cannot infer unwinding by `fn_def_id` for a virtual call.
|
||||||
|
determined_fn_def_id,
|
||||||
|
sig.abi,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
fn_abi_adjust_for_abi(
|
fn_abi_adjust_for_abi(
|
||||||
cx,
|
cx,
|
||||||
|
@ -642,7 +649,7 @@ fn fn_abi_new_uncached<'tcx>(
|
||||||
// If this is a virtual call, we cannot pass the `fn_def_id`, as it might call other
|
// If this is a virtual call, we cannot pass the `fn_def_id`, as it might call other
|
||||||
// functions from vtable. Internally, `deduced_param_attrs` attempts to infer attributes by
|
// functions from vtable. Internally, `deduced_param_attrs` attempts to infer attributes by
|
||||||
// visit the function body.
|
// visit the function body.
|
||||||
fn_def_id.filter(|_| !is_virtual_call),
|
determined_fn_def_id,
|
||||||
);
|
);
|
||||||
debug!("fn_abi_new_uncached = {:?}", fn_abi);
|
debug!("fn_abi_new_uncached = {:?}", fn_abi);
|
||||||
fn_abi_sanity_check(cx, &fn_abi, sig.abi);
|
fn_abi_sanity_check(cx, &fn_abi, sig.abi);
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
//@ compile-flags: -C opt-level=3 -C no-prepopulate-passes
|
//@ compile-flags: -C opt-level=3 -C no-prepopulate-passes
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
pub trait Trait {
|
pub trait Trait {
|
||||||
|
#[rustc_nounwind]
|
||||||
fn m(&self, _: (i32, i32, i32)) {}
|
fn m(&self, _: (i32, i32, i32)) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,3 +18,20 @@ pub fn foo(trait_: &dyn Trait) {
|
||||||
// CHECK-NOT: readonly
|
// CHECK-NOT: readonly
|
||||||
trait_.m((1, 1, 1));
|
trait_.m((1, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[rustc_nounwind]
|
||||||
|
pub fn foo_nounwind(trait_: &dyn Trait) {
|
||||||
|
// CHECK-LABEL: @foo_nounwind(
|
||||||
|
// FIXME: Here should be invoke.
|
||||||
|
// COM: CHECK: invoke
|
||||||
|
trait_.m((1, 1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn c_nounwind(trait_: &dyn Trait) {
|
||||||
|
// CHECK-LABEL: @c_nounwind(
|
||||||
|
// FIXME: Here should be invoke.
|
||||||
|
// COM: CHECK: invoke
|
||||||
|
trait_.m((1, 1, 1));
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue