@@ -19,104 +19,96 @@ use adt;
1919use base:: { self , Lifetime } ;
2020use callee;
2121use builder:: Builder ;
22- use common:: { self , Funclet } ;
23- use common:: { C_bool , C_str_slice , C_struct , C_u32 , C_undef } ;
22+ use common:: { self , C_bool , C_str_slice , C_struct , C_u32 , C_undef } ;
2423use consts;
2524use machine:: llalign_of_min;
2625use meth;
2726use monomorphize;
2827use type_of;
2928use type_:: Type ;
3029
31- use rustc_data_structures:: indexed_vec:: IndexVec ;
3230use syntax:: symbol:: Symbol ;
3331
3432use std:: cmp;
3533
3634use super :: { MirContext , LocalRef } ;
37- use super :: analyze:: CleanupKind ;
3835use super :: constant:: Const ;
3936use super :: lvalue:: { Alignment , LvalueRef } ;
4037use super :: operand:: OperandRef ;
4138use super :: operand:: OperandValue :: { Pair , Ref , Immediate } ;
4239
4340impl < ' a , ' tcx > MirContext < ' a , ' tcx > {
44- pub fn trans_block ( & mut self , bb : mir:: BasicBlock ,
45- funclets : & IndexVec < mir:: BasicBlock , Option < Funclet > > ) {
41+ pub fn trans_block ( & mut self , bb : mir:: BasicBlock ) {
4642 let mut bcx = self . get_builder ( bb) ;
4743 let data = & self . mir [ bb] ;
4844
4945 debug ! ( "trans_block({:?}={:?})" , bb, data) ;
5046
51- let funclet = match self . cleanup_kinds [ bb] {
52- CleanupKind :: Internal { funclet } => funclets[ funclet] . as_ref ( ) ,
53- _ => funclets[ bb] . as_ref ( ) ,
54- } ;
55-
5647 for statement in & data. statements {
5748 bcx = self . trans_statement ( bcx, statement) ;
5849 }
5950
60- self . trans_terminator ( bcx, bb, data. terminator ( ) , funclet ) ;
51+ self . trans_terminator ( bcx, bb, data. terminator ( ) ) ;
6152 }
6253
6354 fn trans_terminator ( & mut self ,
6455 mut bcx : Builder < ' a , ' tcx > ,
6556 bb : mir:: BasicBlock ,
66- terminator : & mir:: Terminator < ' tcx > ,
67- funclet : Option < & Funclet > )
57+ terminator : & mir:: Terminator < ' tcx > )
6858 {
6959 debug ! ( "trans_terminator: {:?}" , terminator) ;
7060
7161 // Create the cleanup bundle, if needed.
7262 let tcx = bcx. tcx ( ) ;
63+ let span = terminator. source_info . span ;
64+ let funclet_bb = self . cleanup_kinds [ bb] . funclet_bb ( bb) ;
65+ let funclet = funclet_bb. and_then ( |funclet_bb| self . funclets [ funclet_bb] . as_ref ( ) ) ;
66+
7367 let cleanup_pad = funclet. map ( |lp| lp. cleanuppad ( ) ) ;
7468 let cleanup_bundle = funclet. map ( |l| l. bundle ( ) ) ;
7569
76- let funclet_br = |this : & Self , bcx : Builder , bb : mir:: BasicBlock | {
77- let lltarget = this. blocks [ bb] ;
78- if let Some ( cp) = cleanup_pad {
79- match this. cleanup_kinds [ bb] {
80- CleanupKind :: Funclet => {
81- // micro-optimization: generate a `ret` rather than a jump
82- // to a return block
83- bcx. cleanup_ret ( cp, Some ( lltarget) ) ;
84- }
85- CleanupKind :: Internal { .. } => bcx. br ( lltarget) ,
86- CleanupKind :: NotCleanup => bug ! ( "jump from cleanup bb to bb {:?}" , bb)
70+ let lltarget = |this : & mut Self , target : mir:: BasicBlock | {
71+ let lltarget = this. blocks [ target] ;
72+ let target_funclet = this. cleanup_kinds [ target] . funclet_bb ( target) ;
73+ match ( funclet_bb, target_funclet) {
74+ ( None , None ) => ( lltarget, false ) ,
75+ ( Some ( f) , Some ( t_f) )
76+ if f == t_f || !base:: wants_msvc_seh ( tcx. sess )
77+ => ( lltarget, false ) ,
78+ ( None , Some ( _) ) => {
79+ // jump *into* cleanup - need a landing pad if GNU
80+ ( this. landing_pad_to ( target) , false )
81+ }
82+ ( Some ( _) , None ) => span_bug ! ( span, "{:?} - jump out of cleanup?" , terminator) ,
83+ ( Some ( _) , Some ( _) ) => {
84+ ( this. landing_pad_to ( target) , true )
8785 }
88- } else {
89- bcx. br ( lltarget) ;
9086 }
9187 } ;
9288
9389 let llblock = |this : & mut Self , target : mir:: BasicBlock | {
94- let lltarget = this. blocks [ target] ;
95-
96- if let Some ( cp) = cleanup_pad {
97- match this. cleanup_kinds [ target] {
98- CleanupKind :: Funclet => {
99- // MSVC cross-funclet jump - need a trampoline
90+ let ( lltarget, is_cleanupret) = lltarget ( this, target) ;
91+ if is_cleanupret {
92+ // MSVC cross-funclet jump - need a trampoline
93+
94+ debug ! ( "llblock: creating cleanup trampoline for {:?}" , target) ;
95+ let name = & format ! ( "{:?}_cleanup_trampoline_{:?}" , bb, target) ;
96+ let trampoline = this. new_block ( name) ;
97+ trampoline. cleanup_ret ( cleanup_pad. unwrap ( ) , Some ( lltarget) ) ;
98+ trampoline. llbb ( )
99+ } else {
100+ lltarget
101+ }
102+ } ;
100103
101- debug ! ( "llblock: creating cleanup trampoline for {:?}" , target) ;
102- let name = & format ! ( "{:?}_cleanup_trampoline_{:?}" , bb, target) ;
103- let trampoline = this. new_block ( name) ;
104- trampoline. cleanup_ret ( cp, Some ( lltarget) ) ;
105- trampoline. llbb ( )
106- }
107- CleanupKind :: Internal { .. } => lltarget,
108- CleanupKind :: NotCleanup =>
109- bug ! ( "jump from cleanup bb {:?} to bb {:?}" , bb, target)
110- }
104+ let funclet_br = |this : & mut Self , bcx : Builder , target : mir:: BasicBlock | {
105+ let ( lltarget, is_cleanupret) = lltarget ( this, target) ;
106+ if is_cleanupret {
107+ // micro-optimization: generate a `ret` rather than a jump
108+ // to a trampoline.
109+ bcx. cleanup_ret ( cleanup_pad. unwrap ( ) , Some ( lltarget) ) ;
111110 } else {
112- if let ( CleanupKind :: NotCleanup , CleanupKind :: Funclet ) =
113- ( this. cleanup_kinds [ bb] , this. cleanup_kinds [ target] )
114- {
115- // jump *into* cleanup - need a landing pad if GNU
116- this. landing_pad_to ( target)
117- } else {
118- lltarget
119- }
111+ bcx. br ( lltarget) ;
120112 }
121113 } ;
122114
@@ -168,7 +160,6 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
168160 }
169161 } ;
170162
171- let span = terminator. source_info . span ;
172163 self . set_debug_loc ( & bcx, terminator. source_info ) ;
173164 match terminator. kind {
174165 mir:: TerminatorKind :: Resume => {
@@ -752,7 +743,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
752743
753744 fn landing_pad_uncached ( & mut self , target_bb : BasicBlockRef ) -> BasicBlockRef {
754745 if base:: wants_msvc_seh ( self . ccx . sess ( ) ) {
755- return target_bb ;
746+ span_bug ! ( self . mir . span , "landing pad was not inserted?" )
756747 }
757748
758749 let bcx = self . new_block ( "cleanup" ) ;
0 commit comments