Skip to content

Commit ca27629

Browse files
committed
Infer effective length for single-blob arrays
1 parent 68bacf4 commit ca27629

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

src/cdomain/value/cdomains/valueDomain.ml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,28 @@ struct
900900
else
901901
x (* This already contains some value *)
902902

903+
let effective_array_length (ask: VDQ.t) (array: CArrays.t) (elem_typ: typ) =
904+
let ik = Cilfacade.ptrdiff_ikind () in
905+
let elem_typ =
906+
match Cil.unrollType elem_typ with
907+
| TArray (elem_typ, _, _) -> elem_typ
908+
| TPtr (elem_typ, _) -> elem_typ
909+
| elem_typ -> elem_typ
910+
in
911+
match CArrays.length array with
912+
| Some l when not (ID.is_bot l) && ID.equal_to Z.one l = `Eq -> begin
913+
match CArrays.get ~checkBounds:false ask array (None, IndexDomain.of_int ik Z.zero) with
914+
| Blob (_, size, _) -> begin
915+
try
916+
let elem_size = ID.of_int ik (Z.of_int (Cilfacade.bytesSizeOf elem_typ)) in
917+
ID.div size elem_size
918+
with Cilfacade.TypeOfError _ -> l
919+
end
920+
| _ -> l
921+
end
922+
| Some l -> l
923+
| None -> ID.top_of ik
924+
903925
(* Funny, this does not compile without the final type annotation! *)
904926
let rec eval_offset (ask: VDQ.t) f (x: t) (offs:offs) (exp:exp option) (v:lval option) (t:typ): t =
905927
let rec do_eval_offset (x:t) (offs:offs) (l:lval option) (o:offset option): t =
@@ -958,6 +980,7 @@ struct
958980
match x with
959981
| Array x ->
960982
let e = determine_offset ask l o exp v in
983+
let x = CArrays.update_length (effective_array_length ask x t) x in
961984
do_eval_offset (CArrays.get ask x (e, idx)) offs l' o'
962985
| Address _ ->
963986
begin
@@ -1133,6 +1156,7 @@ struct
11331156
match x with
11341157
| Array x' ->
11351158
let e = determine_offset ask l o exp (Some v) in
1159+
let x' = CArrays.update_length (effective_array_length ask x' t) x' in
11361160
let new_value_at_index = do_update_offset (CArrays.get ask x' (e,idx)) offs l' o' in
11371161
let new_array_value = CArrays.set ask x' (e, idx) new_value_at_index in
11381162
Array new_array_value

0 commit comments

Comments
 (0)