about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2022-10-10 22:40:40 +0100
committerGary Guo <gary@garyguo.net>2023-04-06 09:34:16 +0100
commit0a5dac3062ffc80a283943e49e2ada08f0b0eaf7 (patch)
tree5110a2f63038db9e3e03883b3d3b5685452a5719 /compiler/rustc_mir_transform/src
parent5e6ed132fa8a1bd1ec6b365e61e9e290528c90f5 (diff)
downloadrust-0a5dac3062ffc80a283943e49e2ada08f0b0eaf7.tar.gz
rust-0a5dac3062ffc80a283943e49e2ada08f0b0eaf7.zip
Add `UnwindAction::Terminate`
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs28
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs6
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs1
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs11
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs1
5 files changed, 15 insertions, 32 deletions
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index 513499927b3..5aed89139e2 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -34,11 +34,6 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
             return;
         }
 
-        // This pass only runs on functions which themselves cannot unwind,
-        // forcibly changing the body of the function to structurally provide
-        // this guarantee by aborting on an unwind. If this function can unwind,
-        // then there's nothing to do because it already should work correctly.
-        //
         // Here we test for this function itself whether its ABI allows
         // unwinding or not.
         let body_ty = tcx.type_of(def_id).skip_binder();
@@ -107,26 +102,9 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
             }
         }
 
-        // For call instructions which need to be terminated, we insert a
-        // singular basic block which simply terminates, and then configure the
-        // `cleanup` attribute for all calls we found to this basic block we
-        // insert which means that any unwinding that happens in the functions
-        // will force an abort of the process.
-        if !calls_to_terminate.is_empty() {
-            let bb = BasicBlockData {
-                statements: Vec::new(),
-                is_cleanup: true,
-                terminator: Some(Terminator {
-                    source_info: SourceInfo::outermost(body.span),
-                    kind: TerminatorKind::Abort,
-                }),
-            };
-            let abort_bb = body.basic_blocks_mut().push(bb);
-
-            for bb in calls_to_terminate {
-                let cleanup = body.basic_blocks_mut()[bb].terminator_mut().unwind_mut().unwrap();
-                *cleanup = UnwindAction::Cleanup(abort_bb);
-            }
+        for id in calls_to_terminate {
+            let cleanup = body.basic_blocks_mut()[id].terminator_mut().unwind_mut().unwrap();
+            *cleanup = UnwindAction::Terminate;
         }
 
         for id in cleanups_to_remove {
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 7d4d33f7450..76fdbcdddd9 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -417,7 +417,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
                                     UnwindAction::Unreachable => {
                                         Unwind::To(self.patch.unreachable_block())
                                     }
-                                    UnwindAction::Terminate => Unwind::To(self.patch.terminate_block()),
+                                    UnwindAction::Terminate => {
+                                        Unwind::To(self.patch.terminate_block())
+                                    }
                                 }
                             };
                             elaborate_drop(
@@ -558,7 +560,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
             if let TerminatorKind::Call {
                 destination,
                 target: Some(_),
-                unwind: UnwindAction::Continue,
+                unwind: UnwindAction::Continue | UnwindAction::Unreachable | UnwindAction::Terminate,
                 ..
             } = data.terminator().kind
             {
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 8a4c3cc247a..bc147d38405 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -1064,6 +1064,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                 UnwindAction::Cleanup(tgt) => tgt,
                 UnwindAction::Continue => elaborator.patch.resume_block(),
                 UnwindAction::Unreachable => elaborator.patch.unreachable_block(),
+                UnwindAction::Terminate => elaborator.patch.terminate_block(),
             })
         };
         elaborate_drop(
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index a4a1acfe428..b1480a524e5 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -1017,15 +1017,15 @@ impl Integrator<'_, '_> {
     fn map_unwind(&self, unwind: UnwindAction) -> UnwindAction {
         if self.in_cleanup_block {
             match unwind {
-                UnwindAction::Cleanup(_) => {
+                UnwindAction::Cleanup(_) | UnwindAction::Continue => {
                     bug!("cleanup on cleanup block");
                 }
-                UnwindAction::Continue | UnwindAction::Unreachable => return unwind,
+                UnwindAction::Unreachable | UnwindAction::Terminate => return unwind,
             }
         }
 
         match unwind {
-            UnwindAction::Unreachable => unwind,
+            UnwindAction::Unreachable | UnwindAction::Terminate => unwind,
             UnwindAction::Cleanup(target) => UnwindAction::Cleanup(self.map_block(target)),
             // Add an unwind edge to the original call's cleanup block
             UnwindAction::Continue => self.cleanup_block,
@@ -1141,7 +1141,10 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
                     terminator.kind = TerminatorKind::Goto { target: tgt };
                 }
                 UnwindAction::Continue => (),
-                UnwindAction::Unreachable => {
+                UnwindAction::Unreachable | UnwindAction::Terminate => {
+                    // If the action is terminate, then we would have mapped marked
+                    // all our call-sites as `UnwindAction::Terminate` and no cleanup
+                    // blocks would ever be executed.
                     terminator.kind = TerminatorKind::Unreachable;
                 }
             },
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index 565fe4eb720..7dc5878e047 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -54,7 +54,6 @@ fn lower_slice_len_call<'tcx>(
             args,
             destination,
             target: Some(bb),
-            unwind: UnwindAction::Unreachable,
             from_hir_call: true,
             ..
         } => {