@ -549,104 +549,110 @@ module Val = struct
let traces = traces_of_loc ( Loc . of_path deref_path ) in
let traces = traces_of_loc ( Loc . of_path deref_path ) in
of_c_array_alloc allocsite ~ stride : None ~ offset ~ size ~ traces
of_c_array_alloc allocsite ~ stride : None ~ offset ~ size ~ traces
in
in
let ptr_to_normal_c_array elt =
let deref_kind = SPath . Deref_CPointer in
let deref_path = SPath . deref ~ deref_kind path in
let l = Loc . of_path deref_path in
let traces = traces_of_loc l in
let arrayblk =
let allocsite = Allocsite . make_symbol deref_path in
let stride =
match elt with
| Some { Typ . desc = Tint ikind } ->
Itv . of_int ( Typ . width_of_ikind integer_type_widths ikind )
| _ ->
Itv . nat
in
let is_void = Typ . is_pointer_to_void typ in
let offset =
if SPath . is_cpp_vector_elem path then Itv . zero else Itv . of_offset_path ~ is_void path
in
let size = Itv . of_length_path ~ is_void path in
ArrayBlk . make_c allocsite ~ stride ~ offset ~ size
in
{ bot with arrayblk ; traces }
in
let is_java = Language . curr_language_is Java in
let is_java = Language . curr_language_is Java in
L . d_printfln_escaped " Val.of_path %a : %a%s%s " SPath . pp_partial path ( Typ . pp Pp . text ) typ
L . d_printfln_escaped " Val.of_path %a : %a%s%s " SPath . pp_partial path ( Typ . pp Pp . text ) typ
( if may_last_field then " , may_last_field " else " " )
( if may_last_field then " , may_last_field " else " " )
( if is_java then " , is_java " else " " ) ;
( if is_java then " , is_java " else " " ) ;
match typ . Typ . desc with
match path with
| Tint ( IBool | IChar | ISChar | IUChar | IUShort ) ->
| BoField . Field { fn ; typ } when BufferOverrunField . is_cpp_vector_elem fn ->
let v = itv_val ~ non_int : is_java in
ptr_to_normal_c_array typ
if is_java then set_itv_updated_by_unknown v else set_itv_updated_by_addition v
| _ -> (
| Tfloat _ | Tfun | TVar _ ->
match typ . Typ . desc with
itv_val ~ non_int : true | > set_itv_updated_by_unknown
| Tint ( IBool | IChar | ISChar | IUChar | IUShort ) ->
| Tint _ | Tvoid ->
let v = itv_val ~ non_int : is_java in
itv_val ~ non_int : false | > set_itv_updated_by_addition
if is_java then set_itv_updated_by_unknown v else set_itv_updated_by_addition v
| Tptr ( { desc = Tfun } , _ ) ->
| Tfloat _ | Tfun | TVar _ ->
of_func_ptrs ( FuncPtr . Set . of_path path )
itv_val ~ non_int : true | > set_itv_updated_by_unknown
| Tptr ( { desc = Tstruct name } , _ )
| Tint _ | Tvoid ->
when PatternMatch . is_subtype tenv name StdTyp . Name . Objc . ns_enumerator ->
itv_val ~ non_int : false | > set_itv_updated_by_addition
(* NOTE: It generates a value of NSEnumerator specifically. Especially, it assigns zero to
| Tptr ( { desc = Tfun } , _ ) ->
the offset , rather than a symbol , to avoid precision loss by limited handling of symbolic
of_func_ptrs ( FuncPtr . Set . of_path path )
values in the domain . Although this is an unsound design choice , we expect it should not
| Tptr ( { desc = Tstruct name } , _ )
that harmful for calculating WCET . * )
when PatternMatch . is_subtype tenv name StdTyp . Name . Objc . ns_enumerator ->
let allocsite = SPath . deref ~ deref_kind : Deref_CPointer path | > Allocsite . make_symbol in
(* NOTE: It generates a value of NSEnumerator specifically. Especially, it assigns zero to
let size = Itv . of_length_path ~ is_void : false path in
the offset , rather than a symbol , to avoid precision loss by limited handling of symbolic
{ bot with arrayblk = ArrayBlk . make_c allocsite ~ offset : Itv . zero ~ size ~ stride : Itv . one }
values in the domain . Although this is an unsound design choice , we expect it should not
| Tptr ( elt , _ ) ->
that harmful for calculating WCET . * )
if is_java | | SPath . is_this path then
let allocsite = SPath . deref ~ deref_kind : Deref_CPointer path | > Allocsite . make_symbol in
let deref_kind =
let size = Itv . of_length_path ~ is_void : false path in
if is_java then SPath . Deref_JavaPointer else SPath . Deref_COneValuePointer
{ bot with arrayblk = ArrayBlk . make_c allocsite ~ offset : Itv . zero ~ size ~ stride : Itv . one }
in
| Tptr ( elt , _ ) ->
let deref_path = SPath . deref ~ deref_kind path in
if is_java | | SPath . is_this path then
let l = Loc . of_path deref_path in
let deref_kind =
let traces = traces_of_loc l in
if is_java then SPath . Deref_JavaPointer else SPath . Deref_COneValuePointer
{ bot with powloc = PowLoc . singleton l ; traces }
else
let deref_kind = SPath . Deref_CPointer in
let deref_path = SPath . deref ~ deref_kind path in
let l = Loc . of_path deref_path in
let traces = traces_of_loc l in
let arrayblk =
let allocsite = Allocsite . make_symbol deref_path in
let stride =
match elt . Typ . desc with
| Typ . Tint ikind ->
Itv . of_int ( Typ . width_of_ikind integer_type_widths ikind )
| _ ->
Itv . nat
in
in
let offset =
let deref_path = SPath . deref ~ deref_kind path in
if SPath . is_cpp_vector_elem path then Itv . zero
let l = Loc . of_path deref_path in
else Itv . of_offset_path ~ is_void : ( Typ . is_pointer_to_void typ ) path
let traces = traces_of_loc l in
in
{ bot with powloc = PowLoc . singleton l ; traces }
let size = Itv . of_length_path ~ is_void : ( Typ . is_pointer_to_void typ ) path in
else ptr_to_normal_c_array ( Some elt )
ArrayBlk . make_c allocsite ~ stride ~ offset ~ size
| Tstruct typename -> (
in
match BufferOverrunTypModels . dispatch tenv typename with
{ bot with arrayblk ; traces }
| Some ( CArray { deref_kind ; length } ) ->
| Tstruct typename -> (
let deref_path = SPath . deref ~ deref_kind path in
match BufferOverrunTypModels . dispatch tenv typename with
let size = Itv . of_int_lit length in
| Some ( CArray { deref_kind ; length } ) ->
ptr_to_c_array_alloc deref_path size
let deref_path = SPath . deref ~ deref_kind path in
| Some CppStdVector ->
let size = Itv . of_int_lit length in
let l = Loc . of_path ( SPath . deref ~ deref_kind : Deref_CPointer path ) in
ptr_to_c_array_alloc deref_path size
let traces = traces_of_loc l in
| Some CppStdVector ->
of_loc ~ traces l
let l = Loc . of_path ( SPath . deref ~ deref_kind : Deref_CPointer path ) in
| Some JavaCollection ->
let traces = traces_of_loc l in
let deref_path = SPath . deref ~ deref_kind : Deref_ArrayIndex path in
of_loc ~ traces l
let l = Loc . of_path deref_path in
| Some JavaCollection ->
let traces = traces_of_loc l in
let allocsite = Allocsite . make_symbol deref_path in
let length = Itv . of_length_path ~ is_void : false path in
of_java_array_alloc allocsite ~ length ~ traces
| Some JavaInteger ->
itv_val ~ non_int : false
| None ->
let l = Loc . of_path path in
let traces = traces_of_loc l in
of_loc ~ traces l )
| Tarray { length ; stride } ->
let deref_path = SPath . deref ~ deref_kind : Deref_ArrayIndex path in
let deref_path = SPath . deref ~ deref_kind : Deref_ArrayIndex path in
let l = Loc . of_path deref_path in
let l = Loc . of_path deref_path in
let traces = traces_of_loc l in
let traces = traces_of_loc l in
let allocsite = Allocsite . make_symbol deref_path in
let allocsite = Allocsite . make_symbol deref_path in
let length = Itv . of_length_path ~ is_void : false path in
let size =
of_java_array_alloc allocsite ~ length ~ traces
match length with
| Some JavaInteger ->
| None (* IncompleteArrayType, no-size flexible array *) ->
itv_val ~ non_int : false
Itv . of_length_path ~ is_void : false path
| None ->
| Some length
let l = Loc . of_path path in
when may_last_field && ( IntLit . iszero length | | IntLit . isone length )
let traces = traces_of_loc l in
(* 0/1-sized flexible array *) ->
of_loc ~ traces l )
Itv . of_length_path ~ is_void : false path
| Tarray { length ; stride } ->
| Some length ->
let deref_path = SPath . deref ~ deref_kind : Deref_ArrayIndex path in
Itv . of_big_int ( IntLit . to_big_int length )
let l = Loc . of_path deref_path in
in
let traces = traces_of_loc l in
if is_java then of_java_array_alloc allocsite ~ length : size ~ traces
let allocsite = Allocsite . make_symbol deref_path in
else
let size =
let stride = Option . map stride ~ f : ( fun n -> IntLit . to_int_exn n ) in
match length with
let offset = Itv . zero in
| None (* IncompleteArrayType, no-size flexible array *) ->
of_c_array_alloc allocsite ~ stride ~ offset ~ size ~ traces )
Itv . of_length_path ~ is_void : false path
| Some length
when may_last_field && ( IntLit . iszero length | | IntLit . isone length )
(* 0/1-sized flexible array *) ->
Itv . of_length_path ~ is_void : false path
| Some length ->
Itv . of_big_int ( IntLit . to_big_int length )
in
if is_java then of_java_array_alloc allocsite ~ length : size ~ traces
else
let stride = Option . map stride ~ f : ( fun n -> IntLit . to_int_exn n ) in
let offset = Itv . zero in
of_c_array_alloc allocsite ~ stride ~ offset ~ size ~ traces
let on_demand : default : t -> ? typ : Typ . t -> OndemandEnv . t -> Loc . t -> t =
let on_demand : default : t -> ? typ : Typ . t -> OndemandEnv . t -> Loc . t -> t =