@@ -41,6 +41,10 @@ let int_of_scalar ?(scalewith=Z.one) ?round (scalar: Scalar.t) =
4141 | _ ->
4242 failwith (" int_of_scalar: unsupported: " ^ Scalar. show scalar)
4343
44+ let int_of_coeff ?scalewith ?round (coeff : Coeff.union_5 ) =
45+ match coeff with
46+ | Scalar scalar -> int_of_scalar ?scalewith ?round scalar
47+ | Interval _ -> None
4448
4549module type ConvertArg =
4650sig
@@ -269,37 +273,44 @@ struct
269273
270274 let longlong = TInt (ILongLong ,[] )
271275
276+ let int_of_coeff_warn ~scalewith coeff =
277+ match int_of_coeff ~scalewith coeff with
278+ | Some i -> i
279+ | None ->
280+ M. warn ~category: Analyzer " Invariant Apron: coefficient is not int: %a" Coeff. pretty coeff;
281+ raise Unsupported_Linexpr1
272282
273283 (* * Returned boolean indicates whether returned expression should be negated. *)
274- let coeff_to_const ~scalewith (c :Coeff.union_5 ) =
275- match c with
276- | Scalar c ->
277- (match int_of_scalar ?scalewith c with
278- | Some i ->
279- let ci,truncation = truncateCilint ILongLong i in
280- if truncation = NoTruncation then
281- if Z. compare i Z. zero > = 0 then
282- false , Const (CInt (i,ILongLong ,None ))
283- else
284- (* attempt to negate if that does not cause an overflow *)
285- let cneg, truncation = truncateCilint ILongLong (Z. neg i) in
286- if truncation = NoTruncation then
287- true , Const (CInt ((Z. neg i),ILongLong ,None ))
288- else
289- false , Const (CInt (i,ILongLong ,None ))
290- else
291- (M. warn ~category: Analyzer " Invariant Apron: coefficient is not int: %a" Scalar. pretty c; raise Unsupported_Linexpr1 )
292- | None -> raise Unsupported_Linexpr1 )
293- | _ -> raise Unsupported_Linexpr1
284+ let cil_exp_of_int i =
285+ let ci,truncation = truncateCilint ILongLong i in
286+ if truncation = NoTruncation then
287+ if Z. compare i Z. zero > = 0 then
288+ false , Const (CInt (i,ILongLong ,None ))
289+ else
290+ (* attempt to negate if that does not cause an overflow *)
291+ let cneg, truncation = truncateCilint ILongLong (Z. neg i) in
292+ if truncation = NoTruncation then
293+ true , Const (CInt ((Z. neg i),ILongLong ,None ))
294+ else
295+ false , Const (CInt (i,ILongLong ,None ))
296+ else
297+ raise Unsupported_Linexpr1
294298
295299 (* * Returned boolean indicates whether returned expression should be negated. *)
296300 let cil_exp_of_linexpr1_term ~scalewith (c : Coeff.t ) v =
297301 match V. to_cil_varinfo v with
298302 | Some vinfo when IntDomain.Size. is_cast_injective ~from_type: vinfo.vtype ~to_type: (TInt (ILongLong ,[] )) ->
299303 let var = Cilfacade. mkCast ~e: (Lval (Var vinfo,NoOffset )) ~newt: longlong in
300- let flip, coeff = coeff_to_const ~scalewith c in
301- let prod = BinOp (Mult , coeff, var, longlong) in
302- flip, prod
304+ let i = int_of_coeff_warn ~scalewith c in
305+ if Z. equal i Z. one then
306+ false , var
307+ else if Z. equal i Z. minus_one then
308+ true , var
309+ else (
310+ let flip, coeff = cil_exp_of_int i in
311+ let prod = BinOp (Mult , coeff, var, longlong) in
312+ flip, prod
313+ )
303314 | None ->
304315 M. warn ~category: Analyzer " Invariant Apron: cannot convert to cil var: %a" Var. pretty v;
305316 raise Unsupported_Linexpr1
@@ -308,8 +319,14 @@ struct
308319 raise Unsupported_Linexpr1
309320
310321 (* * Returned booleans indicates whether returned expressions should be negated. *)
311- let cil_exp_of_linexpr1 ?scalewith (linexpr1 :Linexpr1.t ) =
312- let terms = ref [coeff_to_const ~scalewith (Linexpr1. get_cst linexpr1)] in
322+ let cil_exp_of_linexpr1 ~scalewith (linexpr1 :Linexpr1.t ) =
323+ let terms =
324+ let c = Linexpr1. get_cst linexpr1 in
325+ if Coeff. is_zero c then
326+ ref []
327+ else
328+ ref [cil_exp_of_int (int_of_coeff_warn ~scalewith c)]
329+ in
313330 let append_summand (c :Coeff.union_5 ) v =
314331 if not (Coeff. is_zero c) then
315332 terms := cil_exp_of_linexpr1_term ~scalewith c v :: ! terms
@@ -369,7 +386,7 @@ struct
369386 | DISEQ -> Ne
370387 | EQMOD _ -> raise Unsupported_Linexpr1
371388 in
372- Some (Cil. constFold false @@ BinOp (binop, lhs, rhs, TInt (IInt ,[] ))) (* constFold removes multiplication by factor 1 * )
389+ Some (BinOp (binop, lhs, rhs, TInt (IInt ,[] )))
373390 with
374391 Unsupported_Linexpr1 -> None
375392end
0 commit comments