@@ -280,8 +280,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
280
280
}
281
281
}
282
282
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
+ } ;
285
294
let func_name = format ! ( "{:?}" , func_ptr) ;
286
295
let previous_arg_count = args. len ( ) ;
287
296
let orig_args = args;
@@ -424,16 +433,17 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
424
433
self . llbb ( ) . end_with_void_return ( None )
425
434
}
426
435
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
+ }
437
447
self . llbb ( ) . end_with_return ( None , value) ;
438
448
}
439
449
@@ -938,6 +948,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
938
948
element. get_address ( None )
939
949
}
940
950
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 ( ) ) ;
941
953
ptr. dereference_field ( None , struct_type. get_field ( idx as i32 ) ) . get_address ( None )
942
954
}
943
955
else {
@@ -1356,7 +1368,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1356
1368
1357
1369
fn call (
1358
1370
& mut self ,
1359
- _typ : Type < ' gcc > ,
1371
+ typ : Type < ' gcc > ,
1360
1372
_fn_attrs : Option < & CodegenFnAttrs > ,
1361
1373
fn_abi : Option < & FnAbi < ' tcx , Ty < ' tcx > > > ,
1362
1374
func : RValue < ' gcc > ,
@@ -1370,7 +1382,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1370
1382
}
1371
1383
else {
1372
1384
// 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)
1374
1386
} ;
1375
1387
if let Some ( _fn_abi) = fn_abi {
1376
1388
// TODO(bjorn3): Apply function attributes
0 commit comments