let do_cast ~with_alarms t expr =
  let treat inttype =
    match inttype with
    | TInt(kind,_) ->
        let size = Int.of_int (bitsSizeOf inttype) in
        let signed = isSigned kind in
        V.cast ~with_alarms ~signed ~size expr
    | TFloat (FFloat,_) ->
        let addresses, overflow, res = V.cast_float expr in
        if addresses
        then warning_once_current
          "addresses in float";
        if overflow then warning_once_current
          "overflow in float: %a -> %a. assert(Ook)"
          V.pretty expr V.pretty res;
        res
    | TFloat (FDouble,_)
    | TFloat (FLongDouble,_) ->
      expr
    | _ -> assert false
  in
  match unrollType t with
  | TInt _ | TFloat _  as t' ->
      treat t'
  | TPtr _ ->
      treat theMachine.upointType
  | TEnum ({ekind=k},_) -> treat (TInt(k,[]))
  | TComp _ -> expr (* see test [struct_call.c] *)
  | TBuiltin_va_list _ ->
      (match with_alarms.CilE.imprecision_tracing with
       | CilE.Aignore -> ()
       | CilE.Acall f -> f ()
       | CilE.Alog _ ->
           warning_once_current
             "cast to __builtin_va_list is not precisely implemented yet");
      V.topify_arith_origin expr
  | TFun _ -> expr
  | TNamed _ -> assert false
  | TVoid _ -> assert false
  | TArray _ -> assert false