@@ -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 ~check Bounds: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