@@ -20,7 +20,7 @@ use rustc_target::spec::PanicStrategy;
20
20
/// This forces all unwinds, in panic=abort mode happening in foreign code, to
21
21
/// trigger a process abort.
22
22
#[ derive( PartialEq ) ]
23
- pub struct AbortUnwindingCalls ;
23
+ pub ( super ) struct AbortUnwindingCalls ;
24
24
25
25
impl < ' tcx > crate :: MirPass < ' tcx > for AbortUnwindingCalls {
26
26
fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
@@ -50,9 +50,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
50
50
// with a function call, and whose function we're calling may unwind.
51
51
// This will filter to functions with `extern "C-unwind"` ABIs, for
52
52
// example.
53
- let mut calls_to_terminate = Vec :: new ( ) ;
54
- let mut cleanups_to_remove = Vec :: new ( ) ;
55
- for ( id, block) in body. basic_blocks . iter_enumerated ( ) {
53
+ for block in body. basic_blocks . as_mut ( ) {
56
54
if block. is_cleanup {
57
55
continue ;
58
56
}
@@ -61,7 +59,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
61
59
62
60
let call_can_unwind = match & terminator. kind {
63
61
TerminatorKind :: Call { func, .. } => {
64
- let ty = func. ty ( body, tcx) ;
62
+ let ty = func. ty ( & body. local_decls , tcx) ;
65
63
let sig = ty. fn_sig ( tcx) ;
66
64
let fn_def_id = match ty. kind ( ) {
67
65
ty:: FnPtr ( ..) => None ,
@@ -86,33 +84,22 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
86
84
_ => continue ,
87
85
} ;
88
86
89
- // If this function call can't unwind, then there's no need for it
90
- // to have a landing pad. This means that we can remove any cleanup
91
- // registered for it.
92
87
if !call_can_unwind {
93
- cleanups_to_remove. push ( id) ;
94
- continue ;
95
- }
96
-
97
- // Otherwise if this function can unwind, then if the outer function
98
- // can also unwind there's nothing to do. If the outer function
99
- // can't unwind, however, we need to change the landing pad for this
100
- // function call to one that aborts.
101
- if !body_can_unwind {
102
- calls_to_terminate. push ( id) ;
88
+ // If this function call can't unwind, then there's no need for it
89
+ // to have a landing pad. This means that we can remove any cleanup
90
+ // registered for it.
91
+ let cleanup = block. terminator_mut ( ) . unwind_mut ( ) . unwrap ( ) ;
92
+ * cleanup = UnwindAction :: Unreachable ;
93
+ } else if !body_can_unwind {
94
+ // Otherwise if this function can unwind, then if the outer function
95
+ // can also unwind there's nothing to do. If the outer function
96
+ // can't unwind, however, we need to change the landing pad for this
97
+ // function call to one that aborts.
98
+ let cleanup = block. terminator_mut ( ) . unwind_mut ( ) . unwrap ( ) ;
99
+ * cleanup = UnwindAction :: Terminate ( UnwindTerminateReason :: Abi ) ;
103
100
}
104
101
}
105
102
106
- for id in calls_to_terminate {
107
- let cleanup = body. basic_blocks_mut ( ) [ id] . terminator_mut ( ) . unwind_mut ( ) . unwrap ( ) ;
108
- * cleanup = UnwindAction :: Terminate ( UnwindTerminateReason :: Abi ) ;
109
- }
110
-
111
- for id in cleanups_to_remove {
112
- let cleanup = body. basic_blocks_mut ( ) [ id] . terminator_mut ( ) . unwind_mut ( ) . unwrap ( ) ;
113
- * cleanup = UnwindAction :: Unreachable ;
114
- }
115
-
116
103
// We may have invalidated some `cleanup` blocks so clean those up now.
117
104
super :: simplify:: remove_dead_blocks ( body) ;
118
105
}
0 commit comments