@@ -128,19 +128,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
128128
129129 let debugloc = DebugLoc :: None ;
130130 let attrs = attributes:: from_fn_type ( bcx. ccx ( ) , callee. ty ) ;
131- match * targets {
132- mir:: CallTargets :: Return ( ret) => {
133- let llret = build:: Call ( bcx,
134- callee. immediate ( ) ,
135- & llargs[ ..] ,
136- Some ( attrs) ,
137- debugloc) ;
138- if !return_outptr && !common:: type_is_zero_size ( bcx. ccx ( ) , ret_ty) {
139- base:: store_ty ( bcx, llret, call_dest. llval , ret_ty) ;
140- }
141- build:: Br ( bcx, self . llblock ( ret) , debugloc)
142- }
143- mir:: CallTargets :: WithCleanup ( ( ret, cleanup) ) => {
131+ match ( * targets, base:: avoid_invoke ( bcx) ) {
132+ ( mir:: CallTargets :: WithCleanup ( ( ret, cleanup) ) , false ) => {
133+ let cleanup = self . bcx ( cleanup) ;
144134 let landingpad = self . make_landing_pad ( cleanup) ;
145135 build:: Invoke ( bcx,
146136 callee. immediate ( ) ,
@@ -153,6 +143,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
153143 // FIXME: What do we do here?
154144 unimplemented ! ( )
155145 }
146+ } ,
147+ ( t, _) => {
148+ let ret = match t {
149+ mir:: CallTargets :: Return ( ret) => ret,
150+ mir:: CallTargets :: WithCleanup ( ( ret, _) ) => {
151+ // make a landing pad regardless (so it sets the personality slot.
152+ let block = self . unreachable_block ( ) ;
153+ self . make_landing_pad ( block) ;
154+ ret
155+ }
156+ } ;
157+ let llret = build:: Call ( bcx,
158+ callee. immediate ( ) ,
159+ & llargs[ ..] ,
160+ Some ( attrs) ,
161+ debugloc) ;
162+ if !return_outptr && !common:: type_is_zero_size ( bcx. ccx ( ) , ret_ty) {
163+ base:: store_ty ( bcx, llret, call_dest. llval , ret_ty) ;
164+ }
165+ build:: Br ( bcx, self . llblock ( ret) , debugloc)
156166 }
157167 }
158168 } ,
@@ -171,12 +181,9 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
171181 }
172182 let debugloc = DebugLoc :: None ;
173183 let attrs = attributes:: from_fn_type ( bcx. ccx ( ) , callee. ty ) ;
174- match * cleanup {
175- None => {
176- build:: Call ( bcx, callee. immediate ( ) , & llargs[ ..] , Some ( attrs) , debugloc) ;
177- build:: Unreachable ( bcx) ;
178- }
179- Some ( cleanup) => {
184+ match ( * cleanup, base:: avoid_invoke ( bcx) ) {
185+ ( Some ( cleanup) , false ) => {
186+ let cleanup = self . bcx ( cleanup) ;
180187 let landingpad = self . make_landing_pad ( cleanup) ;
181188 let unreachable = self . unreachable_block ( ) ;
182189 build:: Invoke ( bcx,
@@ -187,13 +194,22 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
187194 Some ( attrs) ,
188195 debugloc) ;
189196 }
197+ ( t, _) => {
198+ if t. is_some ( ) {
199+ // make a landing pad regardless, so it sets the personality slot.
200+ let block = self . unreachable_block ( ) ;
201+ self . make_landing_pad ( block) ;
202+ }
203+ build:: Call ( bcx, callee. immediate ( ) , & llargs[ ..] , Some ( attrs) , debugloc) ;
204+ build:: Unreachable ( bcx) ;
205+ }
190206 }
191207 }
192208 }
193209 }
194210
195- fn make_landing_pad ( & mut self , cleanup : mir :: BasicBlock ) -> Block < ' bcx , ' tcx > {
196- let bcx = self . bcx ( cleanup) . fcx . new_block ( true , "cleanup" , None ) ;
211+ fn make_landing_pad ( & mut self , cleanup : Block < ' bcx , ' tcx > ) -> Block < ' bcx , ' tcx > {
212+ let bcx = cleanup. fcx . new_block ( true , "cleanup" , None ) ;
197213 let ccx = bcx. ccx ( ) ;
198214 let llpersonality = bcx. fcx . eh_personality ( ) ;
199215 let llretty = Type :: struct_ ( ccx, & [ Type :: i8p ( ccx) , Type :: i32 ( ccx) ] , false ) ;
@@ -208,7 +224,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
208224 build:: Store ( bcx, llretval, personalityslot)
209225 }
210226 } ;
211- build:: Br ( bcx, self . llblock ( cleanup) , DebugLoc :: None ) ;
227+ build:: Br ( bcx, cleanup. llbb , DebugLoc :: None ) ;
212228 bcx
213229 }
214230
0 commit comments