Skip to content

Commit fcb275f

Browse files
authoredMay 8, 2023
Rollup merge of #104070 - nbdd0121:unwind, r=Amanieu
Prevent aborting guard from aborting the process in a forced unwind Fix #101469
2 parents ce04288 + 16abe6c commit fcb275f

File tree

9 files changed

+54
-9
lines changed

9 files changed

+54
-9
lines changed
 

‎compiler/rustc_codegen_gcc/src/builder.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
12271227
(value1, value2)
12281228
}
12291229

1230+
fn filter_landing_pad(&mut self, pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
1231+
// TODO(antoyo): generate the correct landing pad
1232+
self.cleanup_landing_pad(pers_fn)
1233+
}
1234+
12301235
#[cfg(feature="master")]
12311236
fn resume(&mut self, exn0: RValue<'gcc>, _exn1: RValue<'gcc>) {
12321237
let exn_type = exn0.get_type();

‎compiler/rustc_codegen_llvm/src/builder.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -985,13 +985,20 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
985985

986986
fn cleanup_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
987987
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
988-
let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */);
988+
let landing_pad = self.landing_pad(ty, pers_fn, 0);
989989
unsafe {
990990
llvm::LLVMSetCleanup(landing_pad, llvm::True);
991991
}
992992
(self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
993993
}
994994

995+
fn filter_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
996+
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
997+
let landing_pad = self.landing_pad(ty, pers_fn, 1);
998+
self.add_clause(landing_pad, self.const_array(self.type_i8p(), &[]));
999+
(self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
1000+
}
1001+
9951002
fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) {
9961003
let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
9971004
let mut exn = self.const_poison(ty);

‎compiler/rustc_codegen_ssa/src/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16001600
bx = Bx::build(self.cx, llbb);
16011601

16021602
let llpersonality = self.cx.eh_personality();
1603-
bx.cleanup_landing_pad(llpersonality);
1603+
bx.filter_landing_pad(llpersonality);
16041604

16051605
funclet = None;
16061606
}

‎compiler/rustc_codegen_ssa/src/traits/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ pub trait BuilderMethods<'a, 'tcx>:
274274

275275
// These are used by everyone except msvc
276276
fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
277+
fn filter_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
277278
fn resume(&mut self, exn0: Self::Value, exn1: Self::Value);
278279

279280
// These are used only by msvc

‎library/std/src/personality/dwarf/eh.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub enum EHAction {
4747
None,
4848
Cleanup(usize),
4949
Catch(usize),
50+
Filter(usize),
5051
Terminate,
5152
}
5253

@@ -142,9 +143,11 @@ unsafe fn interpret_cs_action(
142143
let ttype_index = action_reader.read_sleb128();
143144
if ttype_index == 0 {
144145
EHAction::Cleanup(lpad)
145-
} else {
146+
} else if ttype_index > 0 {
146147
// Stop unwinding Rust panics at catch_unwind.
147148
EHAction::Catch(lpad)
149+
} else {
150+
EHAction::Filter(lpad)
148151
}
149152
}
150153
}

‎library/std/src/personality/gcc.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ cfg_if::cfg_if! {
135135
EHAction::None | EHAction::Cleanup(_) => {
136136
return continue_unwind(exception_object, context);
137137
}
138-
EHAction::Catch(_) => {
138+
EHAction::Catch(_) | EHAction::Filter(_) => {
139139
// EHABI requires the personality routine to update the
140140
// SP value in the barrier cache of the exception object.
141141
(*exception_object).private[5] =
@@ -147,7 +147,8 @@ cfg_if::cfg_if! {
147147
} else {
148148
match eh_action {
149149
EHAction::None => return continue_unwind(exception_object, context),
150-
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
150+
EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context),
151+
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
151152
uw::_Unwind_SetGR(
152153
context,
153154
UNWIND_DATA_REG.0,
@@ -201,13 +202,15 @@ cfg_if::cfg_if! {
201202
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
202203
match eh_action {
203204
EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
204-
EHAction::Catch(_) => uw::_URC_HANDLER_FOUND,
205+
EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND,
205206
EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
206207
}
207208
} else {
208209
match eh_action {
209210
EHAction::None => uw::_URC_CONTINUE_UNWIND,
210-
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) => {
211+
// Forced unwinding hits a terminate action.
212+
EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
213+
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
211214
uw::_Unwind_SetGR(
212215
context,
213216
UNWIND_DATA_REG.0,

‎tests/codegen/vec-shrink-panik.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub fn issue71861(vec: Vec<u32>) -> Box<[u32]> {
2525

2626
// Call to panic_cannot_unwind in case of double-panic is expected
2727
// on LLVM 16 and older, but other panics are not.
28-
// CHECK: cleanup
28+
// CHECK: filter
2929
// old-NEXT: ; call core::panicking::panic_cannot_unwind
3030
// old-NEXT: panic_cannot_unwind
3131

@@ -40,7 +40,7 @@ pub fn issue75636<'a>(iter: &[&'a str]) -> Box<[&'a str]> {
4040

4141
// Call to panic_cannot_unwind in case of double-panic is expected,
4242
// on LLVM 16 and older, but other panics are not.
43-
// CHECK: cleanup
43+
// CHECK: filter
4444
// old-NEXT: ; call core::panicking::panic_cannot_unwind
4545
// old-NEXT: panic_cannot_unwind
4646

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# ignore-cross-compile
2+
# only-linux
3+
include ../tools.mk
4+
5+
all: foo
6+
$(call RUN,foo) | $(CGREP) -v "cannot unwind"
7+
8+
foo: foo.rs
9+
$(RUSTC) $<
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Tests that forced unwind through POF Rust frames wouldn't trigger our terminating guards.
2+
3+
#![feature(c_unwind)]
4+
#![no_main]
5+
6+
extern "C-unwind" {
7+
fn pthread_exit(v: *mut core::ffi::c_void) -> !;
8+
}
9+
10+
unsafe extern "C" fn call_pthread_exit() {
11+
pthread_exit(core::ptr::null_mut());
12+
}
13+
14+
#[no_mangle]
15+
unsafe extern "C-unwind" fn main(_argc: core::ffi::c_int, _argv: *mut *mut core::ffi::c_char) {
16+
call_pthread_exit();
17+
}

0 commit comments

Comments
 (0)