let handle_signed_overflow ~with_alarms typ interpreted_e =
  match unrollType typ with
    TInt(kind, _)
      when isSigned kind ->
          let size = bitsSizeOf typ in
          let mn, mx =
            let b = Int.power_two (size-1) in
            Int.neg b, Int.pred b
          in
          let mn64 = Int.to_int64 mn in
          let mx64 = Int.to_int64 mx in
          let warn_under, warn_over =
            try
              let i = V.project_ival interpreted_e in
              let imn, imx = Ival.min_and_max i in
              let u =
                match imn with
                  Some bound when Int.ge bound mn -> None
                | _ -> Some mn64
              in
              let o =
                match imx with
                  Some bound when Int.le bound mx -> None
                | _ -> Some mx64
              in
              u, o
            with V.Not_based_on_null ->
              Some mn64, Some mx64
          in
          ( match warn_under, warn_over with
                NoneNone ->
                  interpreted_e
              | _ ->
                  if Value_parameters.SignedOverflow.get()
                  then 
                      let all_values =
                        Cvalue.V.inject_ival 
                          (Ival.inject_range (Some mn) (Some mx))
                      in
                      CilE.warn_signed_overflow
                        with_alarms
                        warn_under
                        warn_over;
                      V.narrow all_values interpreted_e 
                  else 
                    ( warning_once_current 
                        "2's complement assumed for overflow";
                      interpreted_e ) )
  | _ -> interpreted_e