let rec stripCastsForPtrArith (e:exp): exp =
  match e.enode with
  | CastE(t, e') -> begin
      match unrollType (typeOf e'), unrollType t with
        TPtr (bt1, _), TPtr (bt2, _) -> begin
          try
            if bitsSizeOf bt1 = bitsSizeOf bt2 then (* Okay to strip *)
              stripCastsForPtrArith e'
            else
              e
          with SizeOfError _ -> (* bt1 or bt2 is abstract; don't strip. *)
            e
        end
      (* strip casts from pointers to unsigned int/long*)
      | (TPtr _ as t1), (TInt(ik,_) as t2)
          when bitsSizeOf t1 = bitsSizeOf t2
            && not (isSigned ik) ->
          stripCastsForPtrArith e'
      | (TInt _ as t1), (TInt _ as t2)
          when bitsSizeOf t1 = bitsSizeOf t2 -> (* Okay to strip.*)
          stripCastsForPtrArith e'
      |  _ -> e
    end
  | _ -> e