@@ -39,7 +39,6 @@ enum MergingSucc {
3939struct TerminatorCodegenHelper < ' tcx > {
4040 bb : mir:: BasicBlock ,
4141 terminator : & ' tcx mir:: Terminator < ' tcx > ,
42- funclet_bb : Option < mir:: BasicBlock > ,
4342}
4443
4544impl < ' a , ' tcx > TerminatorCodegenHelper < ' tcx > {
@@ -49,28 +48,24 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
4948 & self ,
5049 fx : & ' b mut FunctionCx < ' a , ' tcx , Bx > ,
5150 ) -> Option < & ' b Bx :: Funclet > {
52- let funclet_bb = self . funclet_bb ?;
53- if base:: wants_msvc_seh ( fx. cx . tcx ( ) . sess ) {
54- // If `landing_pad_for` hasn't been called yet to create the `Funclet`,
55- // it has to be now. This may not seem necessary, as RPO should lead
56- // to all the unwind edges being visited (and so to `landing_pad_for`
57- // getting called for them), before building any of the blocks inside
58- // the funclet itself - however, if MIR contains edges that end up not
59- // being needed in the LLVM IR after monomorphization, the funclet may
60- // be unreachable, and we don't have yet a way to skip building it in
61- // such an eventuality (which may be a better solution than this).
62- if fx. funclets [ funclet_bb] . is_none ( ) {
63- fx. landing_pad_for ( funclet_bb) ;
64- }
65-
66- Some (
67- fx. funclets [ funclet_bb]
68- . as_ref ( )
69- . expect ( "landing_pad_for didn't also create funclets entry" ) ,
70- )
71- } else {
72- None
51+ let cleanup_kinds = ( & fx. cleanup_kinds ) . as_ref ( ) ?;
52+ let funclet_bb = cleanup_kinds[ self . bb ] . funclet_bb ( self . bb ) ?;
53+ // If `landing_pad_for` hasn't been called yet to create the `Funclet`,
54+ // it has to be now. This may not seem necessary, as RPO should lead
55+ // to all the unwind edges being visited (and so to `landing_pad_for`
56+ // getting called for them), before building any of the blocks inside
57+ // the funclet itself - however, if MIR contains edges that end up not
58+ // being needed in the LLVM IR after monomorphization, the funclet may
59+ // be unreachable, and we don't have yet a way to skip building it in
60+ // such an eventuality (which may be a better solution than this).
61+ if fx. funclets [ funclet_bb] . is_none ( ) {
62+ fx. landing_pad_for ( funclet_bb) ;
7363 }
64+ Some (
65+ fx. funclets [ funclet_bb]
66+ . as_ref ( )
67+ . expect ( "landing_pad_for didn't also create funclets entry" ) ,
68+ )
7469 }
7570
7671 /// Get a basic block (creating it if necessary), possibly with cleanup
@@ -104,23 +99,24 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
10499 fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
105100 target : mir:: BasicBlock ,
106101 ) -> ( bool , bool ) {
107- let target_funclet = fx. cleanup_kinds [ target] . funclet_bb ( target) ;
108- let ( needs_landing_pad, is_cleanupret) = match ( self . funclet_bb , target_funclet) {
109- ( None , None ) => ( false , false ) ,
110- ( None , Some ( _) ) => ( true , false ) ,
111- ( Some ( _) , None ) => {
112- let span = self . terminator . source_info . span ;
113- span_bug ! ( span, "{:?} - jump out of cleanup?" , self . terminator) ;
114- }
115- ( Some ( f) , Some ( t_f) ) => {
116- if f == t_f || !base:: wants_msvc_seh ( fx. cx . tcx ( ) . sess ) {
117- ( false , false )
118- } else {
119- ( true , true )
102+ if let Some ( ref cleanup_kinds) = fx. cleanup_kinds {
103+ let funclet_bb = cleanup_kinds[ self . bb ] . funclet_bb ( self . bb ) ;
104+ let target_funclet = cleanup_kinds[ target] . funclet_bb ( target) ;
105+ let ( needs_landing_pad, is_cleanupret) = match ( funclet_bb, target_funclet) {
106+ ( None , None ) => ( false , false ) ,
107+ ( None , Some ( _) ) => ( true , false ) ,
108+ ( Some ( f) , Some ( t_f) ) => ( f != t_f, f != t_f) ,
109+ ( Some ( _) , None ) => {
110+ let span = self . terminator . source_info . span ;
111+ span_bug ! ( span, "{:?} - jump out of cleanup?" , self . terminator) ;
120112 }
121- }
122- } ;
123- ( needs_landing_pad, is_cleanupret)
113+ } ;
114+ ( needs_landing_pad, is_cleanupret)
115+ } else {
116+ let needs_landing_pad = !fx. mir [ self . bb ] . is_cleanup && fx. mir [ target] . is_cleanup ;
117+ let is_cleanupret = false ;
118+ ( needs_landing_pad, is_cleanupret)
119+ }
124120 }
125121
126122 fn funclet_br < Bx : BuilderMethods < ' a , ' tcx > > (
@@ -1253,9 +1249,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12531249 ) -> MergingSucc {
12541250 debug ! ( "codegen_terminator: {:?}" , terminator) ;
12551251
1256- // Create the cleanup bundle, if needed.
1257- let funclet_bb = self . cleanup_kinds [ bb] . funclet_bb ( bb) ;
1258- let helper = TerminatorCodegenHelper { bb, terminator, funclet_bb } ;
1252+ let helper = TerminatorCodegenHelper { bb, terminator } ;
12591253
12601254 let mergeable_succ = || {
12611255 // Note: any call to `switch_to_block` will invalidate a `true` value
0 commit comments