about summary refs log tree commit diff
path: root/library/std
diff options
context:
space:
mode:
Diffstat (limited to 'library/std')
-rw-r--r--library/std/src/personality/dwarf/eh.rs5
-rw-r--r--library/std/src/personality/gcc.rs11
2 files changed, 11 insertions, 5 deletions
diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/personality/dwarf/eh.rs
index 87585a8fcd0..79624703a4c 100644
--- a/library/std/src/personality/dwarf/eh.rs
+++ b/library/std/src/personality/dwarf/eh.rs
@@ -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)
         }
     }
 }
diff --git a/library/std/src/personality/gcc.rs b/library/std/src/personality/gcc.rs
index 0421b47be02..82edb11cbd1 100644
--- a/library/std/src/personality/gcc.rs
+++ b/library/std/src/personality/gcc.rs
@@ -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,