@@ -280,8 +280,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
280280 }
281281 }
282282
283- fn function_ptr_call ( & mut self , func_ptr : RValue < ' gcc > , args : & [ RValue < ' gcc > ] , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
284- let gcc_func = func_ptr. get_type ( ) . dyncast_function_ptr_type ( ) . expect ( "function ptr" ) ;
283+ fn function_ptr_call ( & mut self , typ : Type < ' gcc > , mut func_ptr : RValue < ' gcc > , args : & [ RValue < ' gcc > ] , _funclet : Option < & Funclet > ) -> RValue < ' gcc > {
284+ let gcc_func =
285+ match func_ptr. get_type ( ) . dyncast_function_ptr_type ( ) {
286+ Some ( func) => func,
287+ None => {
288+ // NOTE: due to opaque pointers now being used, we need to cast here.
289+ let new_func_type = typ. dyncast_function_ptr_type ( ) . expect ( "function ptr" ) ;
290+ func_ptr = self . context . new_cast ( None , func_ptr, typ) ;
291+ new_func_type
292+ } ,
293+ } ;
285294 let func_name = format ! ( "{:?}" , func_ptr) ;
286295 let previous_arg_count = args. len ( ) ;
287296 let orig_args = args;
@@ -424,16 +433,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
424433 self . llbb ( ) . end_with_void_return ( None )
425434 }
426435
427- fn ret ( & mut self , value : RValue < ' gcc > ) {
428- let value =
429- if self . structs_as_pointer . borrow ( ) . contains ( & value) {
430- // NOTE: hack to workaround a limitation of the rustc API: see comment on
431- // CodegenCx.structs_as_pointer
432- value. dereference ( None ) . to_rvalue ( )
433- }
434- else {
435- value
436- } ;
436+ fn ret ( & mut self , mut value : RValue < ' gcc > ) {
437+ if self . structs_as_pointer . borrow ( ) . contains ( & value) {
438+ // NOTE: hack to workaround a limitation of the rustc API: see comment on
439+ // CodegenCx.structs_as_pointer
440+ value = value. dereference ( None ) . to_rvalue ( ) ;
441+ }
442+ let expected_return_type = self . current_func ( ) . get_return_type ( ) ;
443+ if !expected_return_type. is_compatible_with ( value. get_type ( ) ) {
444+ // NOTE: due to opaque pointers now being used, we need to cast here.
445+ value = self . context . new_cast ( None , value, expected_return_type) ;
446+ }
437447 self . llbb ( ) . end_with_return ( None , value) ;
438448 }
439449
@@ -938,6 +948,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
938948 element. get_address ( None )
939949 }
940950 else if let Some ( struct_type) = value_type. is_struct ( ) {
951+ // NOTE: due to opaque pointers now being used, we need to bitcast here.
952+ let ptr = self . bitcast_if_needed ( ptr, value_type. make_pointer ( ) ) ;
941953 ptr. dereference_field ( None , struct_type. get_field ( idx as i32 ) ) . get_address ( None )
942954 }
943955 else {
@@ -1356,7 +1368,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
13561368
13571369 fn call (
13581370 & mut self ,
1359- _typ : Type < ' gcc > ,
1371+ typ : Type < ' gcc > ,
13601372 _fn_attrs : Option < & CodegenFnAttrs > ,
13611373 fn_abi : Option < & FnAbi < ' tcx , Ty < ' tcx > > > ,
13621374 func : RValue < ' gcc > ,
@@ -1370,7 +1382,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
13701382 }
13711383 else {
13721384 // If it's a not function that was defined, it's a function pointer.
1373- self . function_ptr_call ( func, args, funclet)
1385+ self . function_ptr_call ( typ , func, args, funclet)
13741386 } ;
13751387 if let Some ( _fn_abi) = fn_abi {
13761388 // TODO(bjorn3): Apply function attributes
0 commit comments