@@ -3408,7 +3408,20 @@ impl<'c> Translation<'c> {
3408
3408
val = transmute_expr ( actual_ty, ty, val) ;
3409
3409
set_unsafe = true ;
3410
3410
} else {
3411
- val = mk ( ) . cast_expr ( val, ty) ;
3411
+ let decl_kind = & self . ast_context [ decl_id] . kind ;
3412
+ let kind_with_declared_args =
3413
+ self . ast_context . fn_decl_ty_with_declared_args ( decl_kind) ;
3414
+
3415
+ if let Some ( ty) = self
3416
+ . ast_context
3417
+ . type_for_kind ( & kind_with_declared_args)
3418
+ . map ( CQualTypeId :: new)
3419
+ {
3420
+ let ty = self . convert_type ( ty. ctype ) ?;
3421
+ val = mk ( ) . cast_expr ( val, ty) ;
3422
+ } else {
3423
+ val = mk ( ) . cast_expr ( val, ty) ;
3424
+ }
3412
3425
}
3413
3426
}
3414
3427
}
@@ -3514,17 +3527,46 @@ impl<'c> Translation<'c> {
3514
3527
_ => { }
3515
3528
}
3516
3529
3517
- let source_ty = self . ast_context [ expr]
3530
+ let mut source_ty = self . ast_context [ expr]
3518
3531
. kind
3519
3532
. get_qual_type ( )
3520
3533
. ok_or_else ( || format_err ! ( "bad source type" ) ) ?;
3521
3534
3522
3535
let val = if is_explicit {
3536
+ // If we're casting a function, look for its declared ty to use as a more
3537
+ // precise source type. The AST node's type will not preserve typedef arg types
3538
+ // but the function's declaration will.
3539
+ if let Some ( func_decl) = self . ast_context . function_declref_decl ( expr) {
3540
+ let kind_with_declared_args =
3541
+ self . ast_context . fn_decl_ty_with_declared_args ( func_decl) ;
3542
+ let func_ty = self
3543
+ . ast_context
3544
+ . type_for_kind ( & kind_with_declared_args)
3545
+ . expect ( & format ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3546
+ let func_ptr_ty = self
3547
+ . ast_context
3548
+ . type_for_kind ( & CTypeKind :: Pointer ( CQualTypeId :: new ( func_ty) ) )
3549
+ . expect ( & format ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3550
+
3551
+ source_ty = CQualTypeId :: new ( func_ptr_ty) ;
3552
+ }
3553
+
3523
3554
let stmts = self . compute_variable_array_sizes ( ctx, ty. ctype ) ?;
3524
3555
let mut val = self . convert_expr ( ctx, expr, None ) ?;
3525
3556
val. prepend_stmts ( stmts) ;
3526
3557
val
3527
3558
} else {
3559
+ // Cast the return types of functions whose return types are synthetic.
3560
+ if let Some ( func_decl) = self . ast_context . function_declref_decl ( expr) {
3561
+ let kind_with_declared_args =
3562
+ self . ast_context . fn_decl_ty_with_declared_args ( func_decl) ;
3563
+ let func_ty = self
3564
+ . ast_context
3565
+ . type_for_kind ( & kind_with_declared_args)
3566
+ . expect ( & format ! ( "no type for kind {kind_with_declared_args:?}" ) ) ;
3567
+ source_ty = CQualTypeId :: new ( func_ty) ;
3568
+ }
3569
+
3528
3570
// In general, if we are casting the result of an expression, then the inner
3529
3571
// expression should be translated to whatever type it normally would.
3530
3572
// But for literals, if we don't absolutely have to cast, we would rather the
@@ -3537,7 +3579,13 @@ impl<'c> Translation<'c> {
3537
3579
return self . convert_expr ( ctx, expr, override_ty) ;
3538
3580
}
3539
3581
}
3540
- self . convert_expr ( ctx, expr, None ) ?
3582
+ if kind == CastKind :: LValueToRValue
3583
+ && Some ( source_ty. ctype ) != override_ty. map ( |x| x. ctype )
3584
+ {
3585
+ self . convert_expr ( ctx, expr, override_ty) ?
3586
+ } else {
3587
+ self . convert_expr ( ctx, expr, None ) ?
3588
+ }
3541
3589
} ;
3542
3590
// Shuffle Vector "function" builtins will add a cast to the output of the
3543
3591
// builtin call which is unnecessary for translation purposes
0 commit comments