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 _ ->
        let size = Int.of_int (bitsSizeOf inttype) in
        let result =
          V.cast ~with_alarms ~signed:true ~size expr
        in
        result
    | _ -> assert false
  in
  match unrollType t with
  | TInt _ | TFloat _  as t' ->
      treat t'
  | TPtr _ ->
      treat theMachine.upointType
  | TEnum _ ->
      if theMachine.enum_are_signed then
        treat (TInt(IInt,[]))
      else treat (TInt(IUInt,[]))
  | 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 ->
           Value_parameters.warning ~once:true ~current:true
             "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