@@ -3408,7 +3408,20 @@ impl<'c> Translation<'c> {
34083408 val = transmute_expr ( actual_ty, ty, val) ;
34093409 set_unsafe = true ;
34103410 } 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+ }
34123425 }
34133426 }
34143427 }
@@ -3514,17 +3527,46 @@ impl<'c> Translation<'c> {
35143527 _ => { }
35153528 }
35163529
3517- let source_ty = self . ast_context [ expr]
3530+ let mut source_ty = self . ast_context [ expr]
35183531 . kind
35193532 . get_qual_type ( )
35203533 . ok_or_else ( || format_err ! ( "bad source type" ) ) ?;
35213534
35223535 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+
35233554 let stmts = self . compute_variable_array_sizes ( ctx, ty. ctype ) ?;
35243555 let mut val = self . convert_expr ( ctx, expr, None ) ?;
35253556 val. prepend_stmts ( stmts) ;
35263557 val
35273558 } 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+
35283570 // In general, if we are casting the result of an expression, then the inner
35293571 // expression should be translated to whatever type it normally would.
35303572 // But for literals, if we don't absolutely have to cast, we would rather the
@@ -3537,7 +3579,13 @@ impl<'c> Translation<'c> {
35373579 return self . convert_expr ( ctx, expr, override_ty) ;
35383580 }
35393581 }
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+ }
35413589 } ;
35423590 // Shuffle Vector "function" builtins will add a cast to the output of the
35433591 // builtin call which is unnecessary for translation purposes
0 commit comments