summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2022-10-10 19:50:49 +0100
committerGary Guo <gary@garyguo.net>2023-04-06 09:34:16 +0100
commit5e6ed132fa8a1bd1ec6b365e61e9e290528c90f5 (patch)
tree1e0d532ba1afa977d46dcd187a260d499d6467b4 /compiler/rustc_codegen_ssa/src
parentdaeb844e0ccddb9e058128974b290f2022e88be7 (diff)
downloadrust-5e6ed132fa8a1bd1ec6b365e61e9e290528c90f5.tar.gz
rust-5e6ed132fa8a1bd1ec6b365e61e9e290528c90f5.zip
Add `UnwindAction::Unreachable`
This also makes eval machine's `StackPopUnwind`
redundant so that is replaced.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs55
1 files changed, 33 insertions, 22 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index a6891a8ff2f..66bec6f30de 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -156,7 +156,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
         fn_ptr: Bx::Value,
         llargs: &[Bx::Value],
         destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>,
-        unwind: mir::UnwindAction,
+        mut unwind: mir::UnwindAction,
         copied_constant_arguments: &[PlaceRef<'tcx, <Bx as BackendTypes>::Value>],
         mergeable_succ: bool,
     ) -> MergingSucc {
@@ -164,27 +164,28 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
         // do an invoke, otherwise do a call.
         let fn_ty = bx.fn_decl_backend_type(&fn_abi);
 
-        let cleanup = match unwind {
-            mir::UnwindAction::Cleanup(cleanup) => Some(cleanup),
+        if !fn_abi.can_unwind {
+            unwind = mir::UnwindAction::Unreachable;
+        }
+
+        let unwind_block = match unwind {
+            mir::UnwindAction::Cleanup(cleanup) => Some(self.llbb_with_cleanup(fx, cleanup)),
+            _ if fx.mir[self.bb].is_cleanup
+                && fn_abi.can_unwind
+                && !base::wants_msvc_seh(fx.cx.tcx().sess) =>
+            {
+                // Exception must not propagate out of the execution of a cleanup (doing so
+                // can cause undefined behaviour). We insert a double unwind guard for
+                // functions that can potentially unwind to protect against this.
+                //
+                // This is not necessary for SEH which does not use successive unwinding
+                // like Itanium EH. EH frames in SEH are different from normal function
+                // frames and SEH will abort automatically if an exception tries to
+                // propagate out from cleanup.
+                Some(fx.double_unwind_guard())
+            }
             mir::UnwindAction::Continue => None,
-        };
-        let unwind_block = if let Some(cleanup) = cleanup.filter(|_| fn_abi.can_unwind) {
-            Some(self.llbb_with_cleanup(fx, cleanup))
-        } else if fx.mir[self.bb].is_cleanup
-            && fn_abi.can_unwind
-            && !base::wants_msvc_seh(fx.cx.tcx().sess)
-        {
-            // Exception must not propagate out of the execution of a cleanup (doing so
-            // can cause undefined behaviour). We insert a double unwind guard for
-            // functions that can potentially unwind to protect against this.
-            //
-            // This is not necessary for SEH which does not use successive unwinding
-            // like Itanium EH. EH frames in SEH are different from normal function
-            // frames and SEH will abort automatically if an exception tries to
-            // propagate out from cleanup.
-            Some(fx.double_unwind_guard())
-        } else {
-            None
+            mir::UnwindAction::Unreachable => None,
         };
 
         if let Some(unwind_block) = unwind_block {
@@ -640,7 +641,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicCannotUnwind);
 
         // Codegen the actual panic invoke/call.
-        let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &[], None, mir::UnwindAction::Continue, &[], false);
+        let merging_succ = helper.do_call(
+            self,
+            bx,
+            fn_abi,
+            llfn,
+            &[],
+            None,
+            mir::UnwindAction::Unreachable,
+            &[],
+            false,
+        );
         assert_eq!(merging_succ, MergingSucc::False);
     }