Rollup merge of #104070 - nbdd0121:unwind, r=Amanieu
Prevent aborting guard from aborting the process in a forced unwind Fix #101469
This commit is contained in:
commit
fcb275f85e
9 changed files with 54 additions and 9 deletions
|
@ -1227,6 +1227,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
(value1, value2)
|
||||
}
|
||||
|
||||
fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
|
||||
// TODO(antoyo): generate the correct landing pad
|
||||
self.cleanup_landing_pad(pers_fn)
|
||||
}
|
||||
|
||||
#[cfg(feature="master")]
|
||||
fn resume(&mut self, exn0: RValue<'gcc>, _exn1: RValue<'gcc>) {
|
||||
let exn_type = exn0.get_type();
|
||||
|
|
|
@ -985,13 +985,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
|
||||
fn cleanup_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
|
||||
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
|
||||
let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */);
|
||||
let landing_pad = self.landing_pad(ty, pers_fn, 0);
|
||||
unsafe {
|
||||
llvm::LLVMSetCleanup(landing_pad, llvm::True);
|
||||
}
|
||||
(self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
|
||||
}
|
||||
|
||||
fn filter_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
|
||||
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
|
||||
let landing_pad = self.landing_pad(ty, pers_fn, 1);
|
||||
self.add_clause(landing_pad, self.const_array(self.type_i8p(), &[]));
|
||||
(self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
|
||||
}
|
||||
|
||||
fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) {
|
||||
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
|
||||
let mut exn = self.const_poison(ty);
|
||||
|
|
|
@ -1600,7 +1600,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
bx = Bx::build(self.cx, llbb);
|
||||
|
||||
let llpersonality = self.cx.eh_personality();
|
||||
bx.cleanup_landing_pad(llpersonality);
|
||||
bx.filter_landing_pad(llpersonality);
|
||||
|
||||
funclet = None;
|
||||
}
|
||||
|
|
|
@ -274,6 +274,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
|
||||
// These are used by everyone except msvc
|
||||
fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
|
||||
fn filter_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
|
||||
fn resume(&mut self, exn0: Self::Value, exn1: Self::Value);
|
||||
|
||||
// These are used only by msvc
|
||||
|
|
|
@ -47,6 +47,7 @@ pub enum EHAction {
|
|||
None,
|
||||
Cleanup(usize),
|
||||
Catch(usize),
|
||||
Filter(usize),
|
||||
Terminate,
|
||||
}
|
||||
|
||||
|
@ -142,9 +143,11 @@ unsafe fn interpret_cs_action(
|
|||
let ttype_index = action_reader.read_sleb128();
|
||||
if ttype_index == 0 {
|
||||
EHAction::Cleanup(lpad)
|
||||
} else {
|
||||
} else if ttype_index > 0 {
|
||||
// Stop unwinding Rust panics at catch_unwind.
|
||||
EHAction::Catch(lpad)
|
||||
} else {
|
||||
EHAction::Filter(lpad)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ cfg_if::cfg_if! {
|
|||
EHAction::None | EHAction::Cleanup(_) => {
|
||||
return continue_unwind(exception_object, context);
|
||||
}
|
||||
EHAction::Catch(_) => {
|
||||
EHAction::Catch(_) | EHAction::Filter(_) => {
|
||||
// EHABI requires the personality routine to update the
|
||||
// SP value in the barrier cache of the exception object.
|
||||
(*exception_object).private[5] =
|
||||
|
@ -147,7 +147,8 @@ cfg_if::cfg_if! {
|
|||
} else {
|
||||
match eh_action {
|
||||
EHAction::None => return continue_unwind(exception_object, context),
|
||||
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
|
||||
EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context),
|
||||
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
|
||||
uw::_Unwind_SetGR(
|
||||
context,
|
||||
UNWIND_DATA_REG.0,
|
||||
|
@ -201,13 +202,15 @@ cfg_if::cfg_if! {
|
|||
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
|
||||
match eh_action {
|
||||
EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
|
||||
EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND,
|
||||
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
|
||||
}
|
||||
} else {
|
||||
match eh_action {
|
||||
EHAction::None => uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
|
||||
// Forced unwinding hits a terminate action.
|
||||
EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
|
||||
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
|
||||
uw::_Unwind_SetGR(
|
||||
context,
|
||||
UNWIND_DATA_REG.0,
|
||||
|
|
|
@ -25,7 +25,7 @@ pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> {
|
|||
|
||||
// Call to panic_cannot_unwind in case of double-panic is expected
|
||||
// on LLVM 16 and older, but other panics are not.
|
||||
// CHECK: cleanup
|
||||
// CHECK: filter
|
||||
// old-NEXT: ; call core::panicking::panic_cannot_unwind
|
||||
// old-NEXT: panic_cannot_unwind
|
||||
|
||||
|
@ -40,7 +40,7 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
|
|||
|
||||
// Call to panic_cannot_unwind in case of double-panic is expected,
|
||||
// on LLVM 16 and older, but other panics are not.
|
||||
// CHECK: cleanup
|
||||
// CHECK: filter
|
||||
// old-NEXT: ; call core::panicking::panic_cannot_unwind
|
||||
// old-NEXT: panic_cannot_unwind
|
||||
|
||||
|
|
9
tests/run-make/forced-unwind-terminate-pof/Makefile
Normal file
9
tests/run-make/forced-unwind-terminate-pof/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
# ignore-cross-compile
|
||||
# only-linux
|
||||
include ../tools.mk
|
||||
|
||||
all: foo
|
||||
$(call RUN,foo) | $(CGREP) -v "cannot unwind"
|
||||
|
||||
foo: foo.rs
|
||||
$(RUSTC) $<
|
17
tests/run-make/forced-unwind-terminate-pof/foo.rs
Normal file
17
tests/run-make/forced-unwind-terminate-pof/foo.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Tests that forced unwind through POF Rust frames wouldn't trigger our terminating guards.
|
||||
|
||||
#![feature(c_unwind)]
|
||||
#![no_main]
|
||||
|
||||
extern "C-unwind" {
|
||||
fn pthread_exit(v: *mut core::ffi::c_void) -> !;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn call_pthread_exit() {
|
||||
pthread_exit(core::ptr::null_mut());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C-unwind" fn main(_argc: core::ffi::c_int, _argv: *mut *mut core::ffi::c_char) {
|
||||
call_pthread_exit();
|
||||
}
|
Loading…
Add table
Reference in a new issue