Skip to content

Commit 2860a13

Browse files
authored
Merge pull request #766 from goblint/apron-ikind
Follow-up crash fixes to Apron and invariants
2 parents 1673147 + a63af50 commit 2860a13

File tree

6 files changed

+29
-17
lines changed

6 files changed

+29
-17
lines changed

.semgrep/cil.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ rules:
55
- pattern: Cil.typeOfLval
66
- pattern: Cil.typeOfInit
77
- pattern: Cil.typeOffset
8+
- pattern: Cil.mkCast
89
- pattern: Cil.get_stmtLoc
910
paths:
1011
exclude:

src/analyses/apron/apronAnalysis.apron.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ struct
144144

145145
let assert_type_bounds apr x =
146146
assert (AD.varinfo_tracked x);
147-
let ik = Cilfacade.get_ikind x.vtype in
148-
if not (IntDomain.should_ignore_overflow ik) then ( (* don't add type bounds for signed when assume_none *)
147+
match Cilfacade.get_ikind x.vtype with
148+
| ik when not (IntDomain.should_ignore_overflow ik) -> (* don't add type bounds for signed when assume_none *)
149149
let (type_min, type_max) = IntDomain.Size.range ik in
150150
(* TODO: don't go through CIL exp? *)
151151
let apr = AD.assert_inv apr (BinOp (Le, Lval (Cil.var x), (Cil.kintegerCilint ik (Cilint.cilint_of_big_int type_max)), intType)) false in
152152
let apr = AD.assert_inv apr (BinOp (Ge, Lval (Cil.var x), (Cil.kintegerCilint ik (Cilint.cilint_of_big_int type_min)), intType)) false in
153153
apr
154-
)
155-
else
154+
| _
155+
| exception Invalid_argument _ ->
156156
apr
157157

158158

src/analyses/base.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ struct
511511
let toInt i =
512512
match IdxDom.to_int @@ ID.cast_to ik i with
513513
| Some x -> Const (CInt (x,ik, None))
514-
| _ -> mkCast ~e:(Const (CStr ("unknown",No_encoding))) ~newt:intType
514+
| _ -> Cilfacade.mkCast ~e:(Const (CStr ("unknown",No_encoding))) ~newt:intType
515515

516516
in
517517
match o with

src/cdomains/apron/apronDomain.apron.ml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,12 @@ struct
269269
| BinOp (Mod, e1, e2, _) ->
270270
Binop (Mod, texpr1_expr_of_cil_exp e1, texpr1_expr_of_cil_exp e2, Int, Near)
271271
| CastE (TInt _ as t, e) ->
272-
begin match Cilfacade.typeOf e with
273-
| e_typ when IntDomain.Size.is_cast_injective ~from_type:e_typ ~to_type:t -> (* TODO: unnecessary cast check due to overflow check below? or maybe useful in general to also assume type bounds based on argument types? *)
272+
begin match IntDomain.Size.is_cast_injective ~from_type:(Cilfacade.typeOf e) ~to_type:t with (* TODO: unnecessary cast check due to overflow check below? or maybe useful in general to also assume type bounds based on argument types? *)
273+
| true ->
274274
Unop (Cast, texpr1_expr_of_cil_exp e, Int, Zero) (* TODO: what does Apron Cast actually do? just for floating point and rounding? *)
275-
| _
276-
| exception Cilfacade.TypeOfError _ -> (* typeOf inner e, not outer exp *)
275+
| false
276+
| exception Cilfacade.TypeOfError _ (* typeOf inner e, not outer exp *)
277+
| exception Invalid_argument _ -> (* get_ikind in is_cast_injective *)
277278
raise Unsupported_CilExp
278279
end
279280
| _ ->
@@ -289,7 +290,8 @@ struct
289290
raise Unsupported_CilExp
290291
);
291292
expr
292-
| exception Cilfacade.TypeOfError _ ->
293+
| exception Cilfacade.TypeOfError _
294+
| exception Invalid_argument _ ->
293295
raise Unsupported_CilExp
294296
in
295297
texpr1_expr_of_cil_exp
@@ -366,7 +368,7 @@ struct
366368
match V.to_cil_varinfo fundec v with
367369
| Some vinfo ->
368370
(* TODO: What to do with variables that have a type that cannot be stored into ILongLong to avoid overflows? *)
369-
let var = Cil.mkCast ~e:(Lval(Var vinfo,NoOffset)) ~newt:longlong in
371+
let var = Cilfacade.mkCast ~e:(Lval(Var vinfo,NoOffset)) ~newt:longlong in
370372
let coeff, flip = coeff_to_const true c in
371373
let prod = BinOp(Mult, coeff, var, longlong) in
372374
if flip then
@@ -884,7 +886,8 @@ struct
884886
let eval_int d e =
885887
let module ID = Queries.ID in
886888
match Cilfacade.get_ikind_exp e with
887-
| exception Cilfacade.TypeOfError _ ->
889+
| exception Cilfacade.TypeOfError _
890+
| exception Invalid_argument _ ->
888891
ID.top () (* real top, not a top of any ikind because we don't even know the ikind *)
889892
| ik ->
890893
if M.tracing then M.trace "apron" "eval_int: exp_is_cons %a = %B\n" d_plainexp e (exp_is_cons e);

src/cdomains/intDomain.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ struct
319319
let name () = "IntDomLifter(" ^ (I.name ()) ^ ")"
320320
let to_yojson x = I.to_yojson x.v
321321
let invariant e x =
322-
let e' = Cil.(mkCast ~e ~newt:(TInt (x.ikind, []))) in
322+
let e' = Cilfacade.mkCast ~e ~newt:(TInt (x.ikind, [])) in
323323
I.invariant_ikind e' x.ikind x.v
324324
let tag x = I.tag x.v
325325
let arbitrary ik = failwith @@ "Arbitrary not implement for " ^ (name ()) ^ "."

src/util/cilfacade.ml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,14 @@ let getFuns fileAST : startfuns =
315315
let getFirstStmt fd = List.hd fd.sbody.bstmts
316316

317317

318-
(* Returns the ikind of a TInt(_) and TEnum(_). Unrolls typedefs. Warns if a a different type is put in and return IInt *)
318+
(* Returns the ikind of a TInt(_) and TEnum(_). Unrolls typedefs. *)
319319
let rec get_ikind t =
320320
(* important to unroll the type here, otherwise problems with typedefs *)
321321
match Cil.unrollType t with
322322
| TInt (ik,_)
323323
| TEnum ({ekind = ik; _},_) -> ik
324324
| TPtr _ -> get_ikind !Cil.upointType
325-
| _ ->
326-
Messages.warn "Something that we expected to be an integer type has a different type, assuming it is an IInt";
327-
Cil.IInt
325+
| _ -> invalid_arg ("Cilfacade.get_ikind: non-integer type " ^ CilType.Typ.show t)
328326

329327
let ptrdiff_ikind () = get_ikind !ptrdiffType
330328

@@ -444,6 +442,16 @@ and typeOffset basetyp =
444442
| _ -> raise (TypeOfError Field_NonCompound)
445443

446444

445+
(** {!Cil.mkCast} using our {!typeOf}. *)
446+
let mkCast ~(e: exp) ~(newt: typ) =
447+
let oldt =
448+
try
449+
typeOf e
450+
with TypeOfError _ -> (* e might involve alloc variables, weird offsets, etc *)
451+
Cil.voidType (* oldt is only used for avoiding duplicate cast, so this falls back to adding cast *)
452+
in
453+
Cil.mkCastT ~e ~oldt ~newt
454+
447455
let get_ikind_exp e = get_ikind (typeOf e)
448456

449457

0 commit comments

Comments
 (0)