Use a record for struct types instead of a 7-tuple.

Reviewed By: jeremydubreil, sblackshear

Differential Revision: D2863956

fb-gh-sync-id: 166647e
master
Cristiano Calcagno 9 years ago committed by facebook-github-bot-1
parent a317ac38f2
commit 162dc42b5b

@ -423,7 +423,8 @@ let typ_get_recursive_flds tenv te =
(match typ with
| Sil.Tvar _ -> assert false (* there should be no indirection *)
| Sil.Tint _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tfloat _ | Sil.Tenum _ -> []
| Sil.Tstruct (fld_typ_ann_list, _, _, _, _, _, _) -> IList.map (fun (x, y, z) -> x) (IList.filter filter fld_typ_ann_list)
| Sil.Tstruct { Sil.instance_fields } ->
IList.map (fun (x, y, z) -> x) (IList.filter filter instance_fields)
| Sil.Tarray _ -> [])
| Sil.Var _ -> [] (* type of |-> not known yet *)
| Sil.Const _ -> []
@ -769,9 +770,9 @@ let is_simply_recursive tenv tname =
assert false (* there should be no indirection *)
| Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tenum _ ->
None
| Sil.Tstruct (fld_typ_ann_list, _, _, _, _, _, _) ->
| Sil.Tstruct { Sil.instance_fields } ->
begin
match (IList.filter filter fld_typ_ann_list) with
match (IList.filter filter instance_fields) with
| [(fld, _, _)] -> Some fld
| _ -> None
end
@ -1192,10 +1193,11 @@ let cycle_has_weak_or_unretained_or_assign_field cycle =
(* returns items annotation for field fn in struct t *)
let get_item_annotation t fn =
match t with
| Sil.Tstruct(nsf, sf, _, _, _, _, _) ->
| Sil.Tstruct { Sil.instance_fields; static_fields } ->
let ia = ref [] in
IList.iter (fun (fn', t', ia') ->
if Ident.fieldname_equal fn fn' then ia := ia') (nsf@sf);
if Ident.fieldname_equal fn fn' then ia := ia')
(instance_fields @ static_fields);
!ia
| _ -> [] in
let rec has_weak_or_unretained_or_assign params =

@ -66,9 +66,11 @@ end = struct
let rec get_strexp_at_syn_offsets se t syn_offs =
match se, t, syn_offs with
| _, _, [] -> (se, t)
| Sil.Estruct (fsel, _), Sil.Tstruct (ftal, sftal, _, _, _, _, _), Field (fld, _) :: syn_offs' ->
| Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields }, Field (fld, _) :: syn_offs' ->
let se' = snd (IList.find (fun (f', se') -> Sil.fld_equal f' fld) fsel) in
let t' = (fun (x,y,z) -> y) (IList.find (fun (f', t', a') -> Sil.fld_equal f' fld) ftal) in
let t' = (fun (x,y,z) -> y)
(IList.find (fun (f', t', a') ->
Sil.fld_equal f' fld) instance_fields) in
get_strexp_at_syn_offsets se' t' syn_offs'
| Sil.Earray (size, esel, _), Sil.Tarray(t', _), Index ind :: syn_offs' ->
let se' = snd (IList.find (fun (i', se') -> Sil.exp_equal i' ind) esel) in
@ -84,9 +86,11 @@ end = struct
match se, t, syn_offs with
| _, _, [] ->
update se t
| Sil.Estruct (fsel, inst), Sil.Tstruct (ftal, sftal, _, _, _, _, _), Field (fld, _) :: syn_offs' ->
| Sil.Estruct (fsel, inst), Sil.Tstruct { Sil.instance_fields }, Field (fld, _) :: syn_offs' ->
let se' = snd (IList.find (fun (f', _) -> Sil.fld_equal f' fld) fsel) in
let t' = (fun (x,y,z) -> y) (IList.find (fun (f', _, _) -> Sil.fld_equal f' fld) ftal) in
let t' = (fun (x,y,z) -> y)
(IList.find (fun (f', _, _) ->
Sil.fld_equal f' fld) instance_fields) in
let se_mod = replace_strexp_at_syn_offsets se' t' syn_offs' update in
let fsel' = IList.map (fun (f'', se'') -> if Sil.fld_equal f'' fld then (fld, se_mod) else (f'', se'')) fsel in
Sil.Estruct (fsel', inst)
@ -142,8 +146,8 @@ end = struct
if pred sigma_other (path, se, typ) then found := (sigma, hpred, offs') :: !found
else begin
match se, typ with
| Sil.Estruct (fsel, _), Sil.Tstruct (ftal, sftal, _, _, _, _, _) ->
find_offset_fsel sigma_other hpred root offs fsel ftal typ
| Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields } ->
find_offset_fsel sigma_other hpred root offs fsel instance_fields typ
| Sil.Earray (size, esel, _), Sil.Tarray (t, _) ->
find_offset_esel sigma_other hpred root offs esel t
| _ -> ()

@ -304,8 +304,8 @@ let create_idmap sigma : idmap =
let rec do_se se typ = match se, typ with
| Sil.Eexp (e, inst), _ ->
do_exp e typ
| Sil.Estruct (fsel, _), Sil.Tstruct (ftal, sftal, _, _, _, _, _) ->
do_struct fsel ftal
| Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields } ->
do_struct fsel instance_fields
| Sil.Earray (size, esel, _), Sil.Tarray (typ, size') ->
do_se (Sil.Eexp (size, Sil.inst_none)) (Sil.Tint Sil.IULong);
do_array esel typ
@ -419,9 +419,10 @@ let pp_texp_for_malloc fmt =
typ
| Sil.Tptr (t, pk) ->
Sil.Tptr (handle_arr_size t, pk)
| Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) ->
Sil.Tstruct (IList.map (fun (f, t, a) ->
(f, handle_arr_size t, a)) ftal, sftal, csu, nameo, supers, def_mthds, iann)
| Sil.Tstruct struct_typ ->
let instance_fields =
IList.map (fun (f, t, a) -> (f, handle_arr_size t, a)) struct_typ.Sil.instance_fields in
Sil.Tstruct { struct_typ with Sil.instance_fields }
| Sil.Tarray (t, e) ->
Sil.Tarray (handle_arr_size t, e) in
function

@ -542,9 +542,12 @@ let vpath_find prop _exp : Sil.dexp option * Sil.typ option =
(match lexp with
| Sil.Lvar pv ->
let typo = match texp with
| Sil.Sizeof (Sil.Tstruct (ftl, ftal, _, _, _, _, _), _) ->
| Sil.Sizeof (Sil.Tstruct struct_typ, _) ->
(try
let _, t, _ = IList.find (fun (_f, _t, _) -> Ident.fieldname_equal _f f) ftl in
let _, t, _ =
IList.find (fun (f', _, _) ->
Ident.fieldname_equal f' f)
struct_typ.Sil.instance_fields in
Some t
with Not_found -> None)
| _ -> None in

@ -604,7 +604,10 @@ let desc_leak hpred_type_opt value_str_opt resource_opt resource_action_opt loc
s, " to ", " on " in
let typ_str =
match hpred_type_opt with
| Some (Sil.Sizeof (Sil.Tstruct (_, _, Csu.Class, Some classname, _, _, _), _))
| Some (Sil.Sizeof (Sil.Tstruct
{ Sil.csu = Csu.Class;
Sil.struct_name = Some classname;
}, _))
when !Config.curr_language = Config.Java ->
" of type " ^ Mangled.to_string classname ^ " "
| _ -> " " in

@ -209,7 +209,7 @@ struct
| Sil.Tptr (styp, _ ) ->
is_core_lib lib styp
| Sil.Tvar (Typename.TN_csu (_, name) )
| Sil.Tstruct (_, _, _, (Some name), _, _, _) ->
| Sil.Tstruct { Sil.struct_name = Some name } ->
let core_lib_types = core_lib_to_type_list lib in
IList.mem (=) (Mangled.to_string name) core_lib_types
| _ -> false

@ -598,21 +598,23 @@ let sym_eval abs e =
eval (Sil.BinOp (Sil.PlusPI, e11, e2'))
| Sil.BinOp
(Sil.PlusA,
(Sil.Sizeof
(Sil.Tstruct (ftal, sftal, csu, name_opt, supers, def_mthds, iann), st) as e1),
(Sil.Sizeof (Sil.Tstruct struct_typ, st) as e1),
e2) ->
(* pattern for extensible structs given a struct declatead as struct s { ... t arr[n] ... },
allocation pattern malloc(sizeof(struct s) + k * siezof(t)) turn it into
struct s { ... t arr[n + k] ... } *)
let e1' = eval e1 in
let e2' = eval e2 in
(match IList.rev ftal, e2' with
(fname, Sil.Tarray(typ, size), _):: ltfa, Sil.BinOp(Sil.Mult, num_elem, Sil.Sizeof (texp, st)) when ftal != [] && Sil.typ_equal typ texp ->
let instance_fields = struct_typ.Sil.instance_fields in
(match IList.rev instance_fields, e2' with
(fname, Sil.Tarray (typ, size), _) :: ltfa,
Sil.BinOp(Sil.Mult, num_elem, Sil.Sizeof (texp, st))
when instance_fields != [] && Sil.typ_equal typ texp ->
let size' = Sil.BinOp(Sil.PlusA, size, num_elem) in
let ltfa' = (fname, Sil.Tarray(typ, size'), Sil.item_annotation_empty) :: ltfa in
Sil.Sizeof
(Sil.Tstruct
(IList.rev ltfa', sftal, csu, name_opt, supers, def_mthds, iann), st)
let struct_typ' =
{ struct_typ with Sil.instance_fields = ltfa' } in
Sil.Sizeof (Sil.Tstruct struct_typ', st)
| _ -> Sil.BinOp(Sil.PlusA, e1', e2'))
| Sil.BinOp (Sil.PlusA as oplus, e1, e2)
| Sil.BinOp (Sil.PlusPI as oplus, e1, e2) ->
@ -853,9 +855,15 @@ and typ_normalize sub typ = match typ with
typ
| Sil.Tptr (t', pk) ->
Sil.Tptr (typ_normalize sub t', pk)
| Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) ->
| Sil.Tstruct struct_typ ->
let fld_norm = IList.map (fun (f, t, a) -> (f, typ_normalize sub t, a)) in
Sil.Tstruct (fld_norm ftal, fld_norm sftal, csu, nameo, supers, def_mthds, iann)
let instance_fields = fld_norm struct_typ.Sil.instance_fields in
let static_fields = fld_norm struct_typ.Sil.static_fields in
Sil.Tstruct
{ struct_typ with
Sil.instance_fields;
static_fields;
}
| Sil.Tarray (t, e) ->
Sil.Tarray (typ_normalize sub t, exp_normalize sub e)
| Sil.Tenum econsts ->
@ -1119,7 +1127,7 @@ let rec create_strexp_of_type tenvo struct_init_mode typ inst =
match typ with
| Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tenum _ ->
Sil.Eexp (init_value (), inst)
| Sil.Tstruct (ftal, sftal, _, _, _, _, _) ->
| Sil.Tstruct { Sil.instance_fields } ->
begin
match struct_init_mode with
| No_init -> Sil.Estruct ([], inst)
@ -1129,7 +1137,7 @@ let rec create_strexp_of_type tenvo struct_init_mode typ inst =
(fld, Sil.Eexp (Sil.exp_one, inst))
else
(fld, create_strexp_of_type tenvo struct_init_mode t inst) in
Sil.Estruct (IList.map f ftal, inst)
Sil.Estruct (IList.map f instance_fields, inst)
end
| Sil.Tarray (_, size) ->
Sil.Earray (size, [], inst)
@ -1661,15 +1669,15 @@ let sigma_intro_nonemptylseg e1 e2 sigma =
f (hpred :: sigma_passed) sigma'
| Sil.Hlseg (Sil.Lseg_PE, para, f1, f2, shared) :: sigma'
when (Sil.exp_equal e1 f1 && Sil.exp_equal e2 f2)
|| (Sil.exp_equal e2 f1 && Sil.exp_equal e1 f2) ->
|| (Sil.exp_equal e2 f1 && Sil.exp_equal e1 f2) ->
f (Sil.Hlseg (Sil.Lseg_NE, para, f1, f2, shared) :: sigma_passed) sigma'
| Sil.Hlseg _ as hpred :: sigma' ->
f (hpred :: sigma_passed) sigma'
| Sil.Hdllseg (Sil.Lseg_PE, para, iF, oB, oF, iB, shared) :: sigma'
when (Sil.exp_equal e1 iF && Sil.exp_equal e2 oF)
|| (Sil.exp_equal e2 iF && Sil.exp_equal e1 oF)
|| (Sil.exp_equal e1 iB && Sil.exp_equal e2 oB)
|| (Sil.exp_equal e2 iB && Sil.exp_equal e1 oB) ->
|| (Sil.exp_equal e2 iF && Sil.exp_equal e1 oF)
|| (Sil.exp_equal e1 iB && Sil.exp_equal e2 oB)
|| (Sil.exp_equal e2 iB && Sil.exp_equal e1 oB) ->
f (Sil.Hdllseg (Sil.Lseg_NE, para, iF, oB, oF, iB, shared) :: sigma_passed) sigma'
| Sil.Hdllseg _ as hpred :: sigma' ->
f (hpred :: sigma_passed) sigma'

@ -1120,7 +1120,7 @@ let exp_imply calc_missing subs e1_in e2_in : subst2 =
| e1, Sil.Var v2 ->
let occurs_check v e = (* check whether [v] occurs in normalized [e] *)
if Sil.fav_mem (Sil.exp_fav e) v
&& Sil.fav_mem (Sil.exp_fav (Prop.exp_normalize_prop Prop.prop_emp e)) v
&& Sil.fav_mem (Sil.exp_fav (Prop.exp_normalize_prop Prop.prop_emp e)) v
then raise (IMPL_EXC ("occurs check", subs, (EXC_FALSE_EXPS (e1, e2)))) in
if Ident.is_primed v2 then
let () = occurs_check v2 e1 in
@ -1414,11 +1414,17 @@ let expand_hpred_pointer calc_index_frame hpred : bool * bool * Sil.hpred =
let t' = match t, typ_fld with
| _, Sil.Tstruct _ -> (* the struct type of fld is known *)
Sil.Sizeof (typ_fld, Sil.Subtype.exact)
| Sil.Sizeof (_t, st), _ -> (* the struct type of fld is not known -- typically Tvoid *)
| Sil.Sizeof (t1, st), _ -> (* the struct type of fld is not known -- typically Tvoid *)
Sil.Sizeof
(Sil.Tstruct
([(fld, _t, Sil.item_annotation_empty)],
[], Csu.Struct, None, [], [], Sil.item_annotation_empty), st)
{ Sil.instance_fields = [(fld, t1, Sil.item_annotation_empty)];
static_fields = [];
csu = Csu.Struct;
struct_name = None;
Sil.superclasses = [];
Sil.def_methods = [];
Sil.struct_annotations = Sil.item_annotation_empty;
}, st)
(* None as we don't know the stuct name *)
| _ -> raise (Failure "expand_hpred_pointer: Unexpected non-sizeof type in Lfield") in
let hpred' = Sil.Hpointsto (e, Sil.Estruct ([(fld, se)], Sil.inst_none), t') in
@ -1448,8 +1454,9 @@ let cloneable_type = Typename.Java.from_string "java.lang.Cloneable"
let is_interface tenv class_name =
match Sil.tenv_lookup tenv class_name with
| Some (Sil.Tstruct (fields, sfields, Csu.Class, Some c1', supers1, methods, iann)) ->
(IList.length fields = 0) && (IList.length methods = 0)
| Some (Sil.Tstruct ( { Sil.csu = Csu.Class; struct_name = Some _ } as struct_typ )) ->
(IList.length struct_typ.Sil.instance_fields = 0) &&
(IList.length struct_typ.Sil.def_methods = 0)
| _ -> false
(** check if c1 is a subclass of c2 *)
@ -1457,8 +1464,8 @@ let check_subclass_tenv tenv c1 c2 =
let rec check cn =
Typename.equal cn c2 || Typename.equal c2 object_type ||
match Sil.tenv_lookup tenv cn with
| Some (Sil.Tstruct (_, _, Csu.Class, Some c1', supers1, _, _)) ->
IList.exists check supers1
| Some (Sil.Tstruct { Sil.struct_name = Some _; csu = Csu.Class; superclasses }) ->
IList.exists check superclasses
| _ -> false in
check c1
@ -1478,8 +1485,8 @@ let check_subtype_basic_type t1 t2 =
(** check if t1 is a subtype of t2 *)
let rec check_subtype tenv t1 t2 =
match t1, t2 with
| Sil.Tstruct (_, _, Csu.Class, Some c1, _, _, _),
Sil.Tstruct (_, _, Csu.Class, Some c2, _, _, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c1 },
Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c2 } ->
let cn1 = Typename.TN_csu (Csu.Class, c1)
and cn2 = Typename.TN_csu (Csu.Class, c2) in
(check_subclass tenv cn1 cn2)
@ -1490,7 +1497,7 @@ let rec check_subtype tenv t1 t2 =
| Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) ->
check_subtype tenv dom_type1 dom_type2
| Sil.Tarray _, Sil.Tstruct (_, _, Csu.Class, Some c2, _, _, _) ->
| Sil.Tarray _, Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c2 } ->
let cn2 = Typename.TN_csu (Csu.Class, c2) in
Typename.equal cn2 serializable_type
|| Typename.equal cn2 cloneable_type
@ -1500,8 +1507,8 @@ let rec check_subtype tenv t1 t2 =
let rec case_analysis_type tenv (t1, st1) (t2, st2) =
match t1, t2 with
| Sil.Tstruct (_, _, Csu.Class, Some c1, _, _, _),
Sil.Tstruct (_, _, Csu.Class, Some c2, _, _, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c1 },
Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c2 } ->
let cn1 = Typename.TN_csu (Csu.Class, c1)
and cn2 = Typename.TN_csu (Csu.Class, c2) in
(Sil.Subtype.case_analysis (cn1, st1) (cn2, st2) (check_subclass tenv) (is_interface tenv))
@ -1512,7 +1519,7 @@ let rec case_analysis_type tenv (t1, st1) (t2, st2) =
| Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) ->
(case_analysis_type tenv (dom_type1, st1) (dom_type2, st2))
| Sil.Tstruct (_, _, Csu.Class, Some c1, _, _, _), Sil.Tarray _ ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c1 }, Sil.Tarray _ ->
let cn1 = Typename.TN_csu (Csu.Class, c1) in
if (Typename.equal cn1 serializable_type
|| Typename.equal cn1 cloneable_type

@ -102,13 +102,14 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
Ident.create kind !max_stamp in
let res =
match t, off with
| Sil.Tstruct (ftal, sftal, _, _, _, _, _),[] ->
| Sil.Tstruct _, [] ->
([], Sil.Estruct ([], inst), t)
| Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann),
| Sil.Tstruct ({ Sil.instance_fields; static_fields } as struct_typ ),
(Sil.Off_fld (f, _)):: off' ->
let _, t', _ =
try
IList.find (fun (f', _, _) -> Ident.fieldname_equal f f') (ftal @ sftal)
IList.find (fun (f', _, _) -> Ident.fieldname_equal f f')
(instance_fields @ static_fields)
with Not_found ->
raise (Exceptions.Bad_footprint (try assert false with Assert_failure x -> x)) in
let atoms', se', res_t' =
@ -116,8 +117,9 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
pname tenv orig_prop footprint_part kind max_stamp t' off' inst in
let se = Sil.Estruct ([(f, se')], inst) in
let replace_typ_of_f (f', t', a') = if Ident.fieldname_equal f f' then (f, res_t', a') else (f', t', a') in
let ftal' = IList.sort Sil.fld_typ_ann_compare (IList.map replace_typ_of_f ftal) in
(atoms', se, Sil.Tstruct (ftal', sftal, csu, nameo, supers, def_mthds, iann))
let instance_fields' =
IList.sort Sil.fld_typ_ann_compare (IList.map replace_typ_of_f instance_fields) in
(atoms', se, Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields'})
| Sil.Tstruct _, (Sil.Off_index e):: off' ->
let atoms', se', res_t' =
create_struct_values
@ -200,11 +202,12 @@ let rec _strexp_extend_values
_strexp_extend_values
pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
| (Sil.Off_fld (f, _)):: off', Sil.Estruct (fsel, inst'),
Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) ->
Sil.Tstruct ({ Sil.instance_fields; static_fields } as struct_typ) ->
let replace_fv new_v fv = if Ident.fieldname_equal (fst fv) f then (f, new_v) else fv in
let _, typ', _ =
try
IList.find (fun (f', t', a') -> Ident.fieldname_equal f f') (ftal @ sftal)
IList.find (fun (f', t', a') -> Ident.fieldname_equal f f')
(instance_fields @ static_fields)
with Not_found ->
raise (Exceptions.Missing_fld (f, try assert false with Assert_failure x -> x)) in
begin
@ -217,9 +220,10 @@ let rec _strexp_extend_values
let replace_fse = replace_fv res_se' in
let res_fsel' = IList.sort Sil.fld_strexp_compare (IList.map replace_fse fsel) in
let replace_fta (f, t, a) = let f', t' = replace_fv res_typ' (f, t) in (f', t', a) in
let res_ftl' = IList.sort Sil.fld_typ_ann_compare (IList.map replace_fta ftal) in
let instance_fields' =
IList.sort Sil.fld_typ_ann_compare (IList.map replace_fta instance_fields) in
let struct_typ =
Sil.Tstruct (res_ftl', sftal, csu, nameo, supers, def_mthds, iann) in
Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in
(res_atoms', Sil.Estruct (res_fsel', inst'), struct_typ) :: acc in
IList.fold_left replace [] atoms_se_typ_list'
with Not_found ->
@ -228,8 +232,9 @@ let rec _strexp_extend_values
pname tenv orig_prop footprint_part kind max_stamp typ' off' inst in
let res_fsel' = IList.sort Sil.fld_strexp_compare ((f, se'):: fsel) in
let replace_fta (f', t', a') = if Ident.fieldname_equal f' f then (f, res_typ', a') else (f', t', a') in
let res_ftl' = IList.sort Sil.fld_typ_ann_compare (IList.map replace_fta ftal) in
let struct_typ = Sil.Tstruct (res_ftl', sftal, csu, nameo, supers, def_mthds, iann) in
let instance_fields' =
IList.sort Sil.fld_typ_ann_compare (IList.map replace_fta instance_fields) in
let struct_typ = Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in
[(atoms', Sil.Estruct (res_fsel', inst'), struct_typ)]
end
| (Sil.Off_fld (f, _)):: off', _, _ ->
@ -801,11 +806,11 @@ let iter_rearrange_pe_dllseg_last recurse_on_iters default_case_iter iter para_d
let type_at_offset texp off =
let rec strip_offset off typ = match off, typ with
| [], _ -> Some typ
| (Sil.Off_fld (f, _)):: off', Sil.Tstruct (ftal, sftal, _, _, _, _, _) ->
| (Sil.Off_fld (f, _)):: off', Sil.Tstruct { Sil.instance_fields } ->
(try
let typ' =
(fun (x, y, z) -> y)
(IList.find (fun (f', t', a') -> Ident.fieldname_equal f f') ftal) in
(IList.find (fun (f', t', a') -> Ident.fieldname_equal f f') instance_fields) in
strip_offset off' typ'
with Not_found -> None)
| (Sil.Off_index _):: off', Sil.Tarray (typ', _) ->

@ -648,6 +648,17 @@ and const =
and struct_fields = (Ident.fieldname * typ * item_annotation) list
(** Type for a structured value. *)
and struct_typ = {
instance_fields : struct_fields; (** non-static fields *)
static_fields : struct_fields; (** static fields *)
csu : Csu.t; (** class/struct/union *)
struct_name : Mangled.t option; (** name *)
superclasses : Typename.t list; (** list of superclasses *)
def_methods : Procname.t list; (** methods defined *)
struct_annotations : item_annotation; (** annotations *)
}
(** types for sil (structured) expressions *)
and typ =
| Tvar of Typename.t (** named type *)
@ -656,12 +667,7 @@ and typ =
| Tvoid (** void type *)
| Tfun of bool (** function type with noreturn attribute *)
| Tptr of typ * ptr_kind (** pointer type *)
| Tstruct of struct_fields * struct_fields * Csu.t * Mangled.t option *
Typename.t list * Procname.t list * item_annotation
(** Structure type with nonstatic and static fields, class/struct/union flag, name,
list of superclasses, methods defined, and annotations.
The fld - typ pairs are always sorted. This means that we don't support programs that exploit specific layouts
of C structs. *)
| Tstruct of struct_typ (** Type for a structured value *)
| Tarray of typ * exp (** array type with fixed size *)
| Tenum of (Mangled.t * const) list
@ -828,8 +834,8 @@ let is_objc_ref_counter_field (fld, t, a) =
let has_objc_ref_counter hpred =
match hpred with
| Hpointsto(_, _, Sizeof(Tstruct(fl, _, _, _, _, _, _), _)) ->
IList.exists is_objc_ref_counter_field fl
| Hpointsto(_, _, Sizeof(Tstruct struct_typ, _)) ->
IList.exists is_objc_ref_counter_field struct_typ.instance_fields
| _ -> false
let objc_class_str = "ObjC-Class"
@ -847,8 +853,8 @@ let cpp_class_annotation =
let is_class_of_language typ class_string =
match typ with
| Tstruct(_, _, Csu.Class, _, _, _, a) ->
(match a with
| Tstruct { csu = Csu.Class; struct_annotations } ->
(match struct_annotations with
| [({ class_name = n; parameters = []}, true)]
when n = class_string -> true
| _ -> false)
@ -1288,6 +1294,13 @@ let rec const_compare (c1 : const) (c2 : const) : int =
| _, Cptr_to_fld _ -> 1
| Ctuple el1, Ctuple el2 -> IList.compare exp_compare el1 el2
and struct_typ_compare struct_typ1 struct_typ2 =
let n = fld_typ_ann_list_compare struct_typ1.instance_fields struct_typ2.instance_fields in
if n <> 0 then n else
let n = fld_typ_ann_list_compare struct_typ1.static_fields struct_typ2.static_fields in
if n <> 0 then n else let n = Csu.compare struct_typ1.csu struct_typ2.csu in
if n <> 0 then n else cname_opt_compare struct_typ1.struct_name struct_typ2.struct_name
(** Comparision for types. *)
and typ_compare t1 t2 =
if t1 == t2 then 0 else match t1, t2 with
@ -1311,12 +1324,8 @@ and typ_compare t1 t2 =
if n <> 0 then n else ptr_kind_compare pk1 pk2
| Tptr _, _ -> - 1
| _, Tptr _ -> 1
| Tstruct (ntal1, sntal1, csu1, nameo1, _, _, _),
Tstruct (ntal2, sntal2, csu2, nameo2, _, _, _) ->
let n = fld_typ_ann_list_compare ntal1 ntal2 in
if n <> 0 then n else let n = fld_typ_ann_list_compare sntal1 sntal2 in
if n <> 0 then n else let n = Csu.compare csu1 csu2 in
if n <> 0 then n else cname_opt_compare nameo1 nameo2
| Tstruct struct_typ1, Tstruct struct_typ2 ->
struct_typ_compare struct_typ1 struct_typ2
| Tstruct _, _ -> - 1
| _, Tstruct _ -> 1
| Tarray (t1, _), Tarray (t2, _) -> typ_compare t1 t2
@ -1969,17 +1978,29 @@ and pp_type_decl pe pp_base pp_size f = function
| Tptr (typ, pk) ->
let pp_base' fmt () = F.fprintf fmt "%s%a" (ptr_kind_string pk) pp_base () in
pp_type_decl pe pp_base' pp_size f typ
| Tstruct (ftal, sftal, csu, Some name, _, _, _) when false ->
| Tstruct ({struct_name = Some name} as struct_typ) when false ->
(* remove "when false" to print the details of struct *)
F.fprintf f "%s %a {%a} %a" (Csu.name csu) Mangled.pp name
F.fprintf f "%s %a {%a} %a"
(Csu.name struct_typ.csu)
Mangled.pp name
(pp_seq (fun f (fld, t, ann) ->
F.fprintf f "%a %a"
(pp_typ_full pe) t
Ident.pp_fieldname fld)) struct_typ.instance_fields
pp_base ()
| Tstruct ({struct_name = Some name} as struct_typ) ->
F.fprintf f "%s %a %a"
(Csu.name struct_typ.csu)
Mangled.pp name
pp_base ()
| Tstruct ({struct_name = None} as struct_typ) ->
F.fprintf f "%s {%a} %a"
(Csu.name struct_typ.csu)
(pp_seq (fun f (fld, t, ann) ->
F.fprintf f "%a %a" (pp_typ_full pe) t Ident.pp_fieldname fld))
ftal pp_base ()
| Tstruct (ftal, sftal, csu, Some name, _, _, _) ->
F.fprintf f "%s %a %a" (Csu.name csu) Mangled.pp name pp_base ()
| Tstruct (ftal, sftal, csu, None, _, _, _) ->
F.fprintf f "%s {%a} %a" (Csu.name csu)
(pp_seq (fun f (fld, t, ann) -> F.fprintf f "%a %a" (pp_typ_full pe) t Ident.pp_fieldname fld)) ftal pp_base ()
F.fprintf f "%a %a"
(pp_typ_full pe) t
Ident.pp_fieldname fld)) struct_typ.instance_fields
pp_base ()
| Tarray (typ, size) ->
let pp_base' fmt () = F.fprintf fmt "%a[%a]" pp_base () (pp_size pe) size in
pp_type_decl pe pp_base' pp_size f typ
@ -2203,8 +2224,8 @@ let rec typ_iter_types (f : typ -> unit) typ =
()
| Tptr (t', pk) ->
typ_iter_types f t'
| Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) ->
IList.iter (fun (_, t, _) -> typ_iter_types f t) ftal
| Tstruct struct_typ ->
IList.iter (fun (_, t, _) -> typ_iter_types f t) struct_typ.instance_fields
| Tarray (t, e) ->
typ_iter_types f t;
exp_iter_types f e
@ -2814,8 +2835,10 @@ let texp_to_typ default_opt = function
let struct_typ_fld default_opt f =
let def () = unsome_typ "struct_typ_fld" default_opt in
function
| Tstruct (ftal, sftal, _, _, _, _, _) ->
(try (fun (x, y, z) -> y) (IList.find (fun (_f, t, ann) -> Ident.fieldname_equal _f f) ftal)
| Tstruct struct_typ ->
(try (fun (x, y, z) -> y)
(IList.find (fun (_f, t, ann) ->
Ident.fieldname_equal _f f) struct_typ.instance_fields)
with Not_found -> def ())
| _ -> def ()

@ -279,6 +279,17 @@ and const =
and struct_fields = (Ident.fieldname * typ * item_annotation) list
(** Type for a structured value. *)
and struct_typ = {
instance_fields : struct_fields; (** non-static fields *)
static_fields : struct_fields; (** static fields *)
csu : Csu.t; (** class/struct/union *)
struct_name : Mangled.t option; (** name *)
superclasses : Typename.t list; (** list of superclasses *)
def_methods : Procname.t list; (** methods defined *)
struct_annotations : item_annotation; (** annotations *)
}
(** Types for sil (structured) expressions. *)
and typ =
| Tvar of Typename.t (** named type *)
@ -287,12 +298,7 @@ and typ =
| Tvoid (** void type *)
| Tfun of bool (** function type with noreturn attribute *)
| Tptr of typ * ptr_kind (** pointer type *)
| Tstruct of struct_fields * struct_fields * Csu.t * Mangled.t option *
Typename.t list * Procname.t list * item_annotation
(** Structure type with nonstatic and static fields, class/struct/union flag, name, list of superclasses,
methods defined, and annotations.
The fld - typ pairs are always sorted. This means that we don't support programs that exploit specific layouts
of C structs. *)
| Tstruct of struct_typ (** Type for a structured value *)
| Tarray of typ * exp (** array type with fixed size *)
| Tenum of (Mangled.t * const) list

@ -42,9 +42,9 @@ let rec unroll_type tenv typ off =
| Sil.Tvar _, _ ->
let typ' = Sil.expand_type tenv typ in
unroll_type tenv typ' off
| Sil.Tstruct (ftal, sftal, _, _, _, _, _), Sil.Off_fld (fld, _) ->
| Sil.Tstruct { Sil.instance_fields; static_fields }, Sil.Off_fld (fld, _) ->
begin
try fldlist_assoc fld (ftal @ sftal)
try fldlist_assoc fld (instance_fields @ static_fields)
with Not_found ->
L.d_strln ".... Invalid Field Access ....";
L.d_strln ("Fld : " ^ Ident.fieldname_to_string fld);
@ -156,10 +156,10 @@ let rec apply_offlist
| (Sil.Off_fld (fld, fld_typ)):: offlist', Sil.Estruct (fsel, inst') ->
begin
let typ' = Sil.expand_type tenv typ in
let ftal, sftal, csu, nameo, supers, def_mthds, iann =
let struct_typ =
match typ' with
| Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) ->
ftal, sftal, csu, nameo, supers, def_mthds, iann
| Sil.Tstruct struct_typ ->
struct_typ
| _ -> assert false in
let t' = unroll_type tenv typ (Sil.Off_fld (fld, fld_typ)) in
try
@ -171,9 +171,9 @@ let rec apply_offlist
let replace_fse fse = if Sil.fld_equal fld (fst fse) then (fld, res_se') else fse in
let res_se = Sil.Estruct (IList.map replace_fse fsel, inst') in
let replace_fta (f, t, a) = if Sil.fld_equal fld f then (fld, res_t', a) else (f, t, a) in
let instance_fields' = IList.map replace_fta struct_typ.Sil.instance_fields in
let res_t =
Sil.Tstruct
(IList.map replace_fta ftal, sftal, csu, nameo, supers, def_mthds, iann) in
Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in
(res_e', res_se, res_t, res_pred_insts_op')
with Not_found ->
pp_error();
@ -606,11 +606,11 @@ let resolve_method tenv class_name proc_name =
Procname.java_replace_class proc_name (Typename.name class_name)
else Procname.c_method_replace_class proc_name (Typename.name class_name) in
match Sil.tenv_lookup tenv class_name with
| Some (Sil.Tstruct (_, _, Csu.Class, cls, super_classes, methods, iann)) ->
if method_exists right_proc_name methods then
| Some (Sil.Tstruct { Sil.csu = Csu.Class; def_methods; superclasses }) ->
if method_exists right_proc_name def_methods then
Some right_proc_name
else
(match super_classes with
(match superclasses with
| super_classname:: interfaces ->
if not (Typename.Set.mem super_classname !visited)
then resolve super_classname
@ -634,8 +634,8 @@ let resolve_typename prop arg =
| _ :: hpreds -> loop hpreds in
loop (Prop.get_sigma prop) in
match typexp_opt with
| Some (Sil.Sizeof (Sil.Tstruct (_, _, _, None, _, _, _), _)) -> None
| Some (Sil.Sizeof (Sil.Tstruct (_, _, Csu.Class, Some name, _, _, _), _)) ->
| Some (Sil.Sizeof (Sil.Tstruct { Sil.struct_name = None }, _)) -> None
| Some (Sil.Sizeof (Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some name }, _)) ->
Some (Typename.TN_csu (Csu.Class, name))
| _ -> None
@ -659,7 +659,7 @@ let resolve_virtual_pname cfg tenv prop args pname call_flags : Procname.t =
let redirect_shared_ptr tenv cfg pname actual_params =
let class_shared_ptr typ =
try match Sil.expand_type tenv typ with
| Sil.Tstruct (_, _, Csu.Class, Some cl_name, _, _, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some cl_name } ->
let name = Mangled.to_string cl_name in
name = "shared_ptr" || name = "__shared_ptr"
| t -> false
@ -1468,7 +1468,7 @@ and sym_exec_call cfg pdesc tenv pre path ret_ids actual_pars summary loc =
| _, [id] -> Errdesc.id_is_assigned_then_dead (State.get_node ()) id
| _ -> false in
if is_ignored
&& Specs.get_flag callee_pname proc_flag_ignore_return = None then
&& Specs.get_flag callee_pname proc_flag_ignore_return = None then
let err_desc = Localise.desc_return_value_ignored callee_pname loc in
let exn = (Exceptions.Return_value_ignored (err_desc, try assert false with Assert_failure x -> x)) in
let pre_opt = State.get_normalized_pre (Abs.abstract_no_symop caller_pname) in

@ -443,9 +443,9 @@ let texp_star texp1 texp2 =
| 0 -> ftal_sub ftal1' ftal2'
| _ -> ftal_sub ftal1 ftal2' end in
let typ_star t1 t2 = match t1, t2 with
| Sil.Tstruct (ftal1, sftal1, csu1, _, _, _, _),
Sil.Tstruct (ftal2, sftal2, csu2, _, _, _, _) when csu1 = csu2 ->
if ftal_sub ftal1 ftal2 then t2 else t1
| Sil.Tstruct { Sil.instance_fields = instance_fields1; csu = csu1 },
Sil.Tstruct { Sil.instance_fields = instance_fields2; csu = csu2 } when csu1 = csu2 ->
if ftal_sub instance_fields1 instance_fields2 then t2 else t1
| _ -> t1 in
match texp1, texp2 with
| Sil.Sizeof (t1, st1), Sil.Sizeof (t2, st2) -> Sil.Sizeof (typ_star t1 t2, Sil.Subtype.join st1 st2)
@ -597,7 +597,8 @@ let prop_get_exn_name pname prop =
let exn_name = ref (Typename.Java.from_string "") in
let find_exn_name e =
let do_hpred = function
| Sil.Hpointsto (e1, _, Sil.Sizeof(Sil.Tstruct (_, _, _, Some name, _, _, _), _)) when Sil.exp_equal e1 e ->
| Sil.Hpointsto (e1, _, Sil.Sizeof (Sil.Tstruct { Sil.struct_name = Some name }, _))
when Sil.exp_equal e1 e ->
let found_exn_name = Typename.TN_csu (Csu.Class, name) in
exn_name := found_exn_name
| _ -> () in

@ -99,8 +99,8 @@ struct
let rec type_to_string typ =
match typ with
| Sil.Tptr (typ , _) -> type_to_string typ
| Sil.Tstruct (_, _, Csu.Class, Some mangled, _, _, _)
| Sil.Tvar (Typename.TN_csu (Csu.Class, (mangled))) -> Mangled.to_string mangled
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some mangled }
| Sil.Tvar (Typename.TN_csu (Csu.Class, mangled)) -> Mangled.to_string mangled
| _ -> Sil.typ_to_string typ
let string_typ_to_string (s, typ) =
@ -311,7 +311,7 @@ let initial_node = ref (Cfg.Node.dummy ())
let rec super tenv t =
match t with
| Sil.Tstruct (_, _, Csu.Class, Some c2, class_name :: rest, _, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some _; superclasses = class_name :: _ } ->
Sil.tenv_lookup tenv class_name
| Sil.Tarray (dom_type, _) -> None
| Sil.Tptr (dom_type, p) ->
@ -430,9 +430,9 @@ struct
| _ ->
let ityp = Sil.expand_type tenv typ in
match ityp with
| Sil.Tstruct (fields, sftal, csu, nameo, supers, def_mthds, iann) ->
| Sil.Tstruct { Sil.instance_fields } ->
let (_, typ, _) =
try ((IList.find (fun (f, t, _) -> Ident.fieldname_equal f field)) fields)
try ((IList.find (fun (f, t, _) -> Ident.fieldname_equal f field)) instance_fields)
with Not_found -> assert false in
typ
| _ -> assert false
@ -488,8 +488,8 @@ struct
let pred =
try IList.find (fun p -> not (Set.mem p set)) preds
with Not_found ->
try IList.hd preds
with Failure "hd" -> Set.min_elt set in
try IList.hd preds
with Failure "hd" -> Set.min_elt set in
(aux pred) in
if (Set.mem old_node set) then backtrack ()
else

@ -37,10 +37,12 @@ let suppressLint = "android.annotation.SuppressLint"
let get_field_type_and_annotation fn = function
| Sil.Tptr (Sil.Tstruct (ftal, sftal, _, _, _, _, _), _)
| Sil.Tstruct (ftal, sftal, _, _, _, _, _) ->
| Sil.Tptr (Sil.Tstruct struct_typ, _)
| Sil.Tstruct struct_typ ->
(try
let (_, t, a) = IList.find (fun (f, t, a) -> Sil.fld_equal f fn) (ftal @ sftal) in
let (_, t, a) = IList.find (fun (f, t, a) ->
Sil.fld_equal f fn)
(struct_typ.Sil.instance_fields @ struct_typ.Sil.static_fields) in
Some (t, a)
with Not_found -> None)
| _ -> None

@ -83,7 +83,7 @@ let callback_checker_main all_procs get_procdesc idenv tenv proc_name proc_desc
let typename =
Typename.TN_csu (Csu.Class, Mangled.from_string (Procname.java_get_class proc_name)) in
match Sil.tenv_lookup tenv typename with
| Some (Sil.Tstruct(_, _, csu, Some class_name, _, methods, _) as typ) ->
| Some (Sil.Tstruct { Sil.csu; struct_name = Some class_name; def_methods } as typ) ->
let lifecycle_typs = get_or_create_lifecycle_typs tenv in
let proc_belongs_to_lifecycle_typ = IList.exists
(fun lifecycle_typ -> AndroidFramework.typ_is_lifecycle_typ typ lifecycle_typ tenv)
@ -96,13 +96,14 @@ let callback_checker_main all_procs get_procdesc idenv tenv proc_name proc_desc
let registered_callback_procs' = IList.fold_left
(fun callback_procs callback_typ ->
match callback_typ with
| Sil.Tptr (Sil.Tstruct(_, _, Csu.Class, Some class_name, _, methods, _), _) ->
| Sil.Tptr (Sil.Tstruct
{ Sil.struct_name = Some _; def_methods = def_methods'}, _) ->
IList.fold_left
(fun callback_procs callback_proc ->
if Procname.is_constructor callback_proc then callback_procs
else Procname.Set.add callback_proc callback_procs)
callback_procs
methods
def_methods'
| typ -> callback_procs)
!registered_callback_procs
registered_callback_typs in
@ -111,6 +112,6 @@ let callback_checker_main all_procs get_procdesc idenv tenv proc_name proc_desc
(* compute the set of fields nullified by this procedure *)
(* TODO (t4959422): get fields that are nullified in callees of the destroy method *)
fields_nullified := FldSet.union (get_fields_nullified proc_desc) !fields_nullified in
if done_checking (IList.length methods) then
if done_checking (IList.length def_methods) then
do_eradicate_check all_procs get_procdesc idenv tenv
| _ -> ()

@ -207,8 +207,8 @@ let callback_check_write_to_parcel all_procs get_proc_desc idenv tenv proc_name
PatternMatch.has_formal_method_argument_type_names proc_desc proc_name ["android.os.Parcel"] in
let parcel_constructors = function
| Sil.Tptr (Sil.Tstruct (_, _, _, _, _, methods, _), _) ->
IList.filter is_parcel_constructor methods
| Sil.Tptr (Sil.Tstruct { Sil.def_methods }, _) ->
IList.filter is_parcel_constructor def_methods
| _ -> [] in
let check r_name r_desc w_name w_desc =

@ -16,7 +16,8 @@ open Utils
let object_name = Mangled.from_string "java.lang.Object"
let type_is_object = function
| Sil.Tptr (Sil.Tstruct (_, _, _, Some name, _, _, _), _) -> Mangled.equal name object_name
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _) ->
Mangled.equal name object_name
| _ -> false
let java_proc_name_with_class_method pn class_with_path method_name =
@ -27,8 +28,8 @@ let java_proc_name_with_class_method pn class_with_path method_name =
let is_direct_subtype_of this_type super_type_name =
match this_type with
| Sil.Tptr (Sil.Tstruct (_, _, _, _, supertypes, _, _), _) ->
IList.exists (fun cn -> Typename.equal cn super_type_name) supertypes
| Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _) ->
IList.exists (fun cn -> Typename.equal cn super_type_name) superclasses
| _ -> false
(** The type the method is invoked on *)
@ -37,12 +38,13 @@ let get_this_type proc_attributes = match proc_attributes.ProcAttributes.formals
| _ -> None
let type_get_direct_supertypes = function
| Sil.Tptr (Sil.Tstruct (_, _, _, _, supertypes, _, _), _)
| Sil.Tstruct (_, _, _, _, supertypes, _, _) -> supertypes
| Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _)
| Sil.Tstruct { Sil.superclasses } ->
superclasses
| _ -> []
let type_get_class_name t = match t with
| Sil.Tptr (Sil.Tstruct (_, _, _, Some cn, _, _, _), _) ->
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some cn }, _) ->
Some cn
| Sil.Tptr (Sil.Tvar (Typename.TN_csu (Csu.Class, cn)), _) ->
Some cn
@ -51,8 +53,9 @@ let type_get_class_name t = match t with
let type_get_annotation
(t: Sil.typ): Sil.item_annotation option =
match t with
| Sil.Tptr (Sil.Tstruct (_, _, _, _, _, _, ia), _)
| Sil.Tstruct (_, _, _, _, _, _, ia) -> Some ia
| Sil.Tptr (Sil.Tstruct { Sil.struct_annotations }, _)
| Sil.Tstruct { Sil.struct_annotations } ->
Some struct_annotations
| _ -> None
let type_has_class_name t name =
@ -71,8 +74,8 @@ let type_has_supertype
else
begin
match Sil.expand_type tenv typ with
| Sil.Tptr (Sil.Tstruct (_, _, _, _, supertypes, _, _), _)
| Sil.Tstruct (_, _, _, _, supertypes, _, _) ->
| Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _)
| Sil.Tstruct { Sil.superclasses } ->
let match_supertype cn =
let match_name () = Typename.equal cn class_name in
let has_indirect_supertype () =
@ -80,15 +83,15 @@ let type_has_supertype
| Some supertype -> has_supertype supertype (Sil.TypSet.add typ visited)
| None -> false in
(match_name () || has_indirect_supertype ()) in
IList.exists match_supertype supertypes
IList.exists match_supertype superclasses
| _ -> false
end in
has_supertype typ Sil.TypSet.empty
let type_is_nested_in_type t n = match t with
| Sil.Tptr (Sil.Tstruct (_, _, _, Some m, _, _, _), _) ->
string_is_prefix (Mangled.to_string n ^ "$") (Mangled.to_string m)
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _) ->
string_is_prefix (Mangled.to_string n ^ "$") (Mangled.to_string name)
| _ -> false
let type_is_nested_in_direct_supertype t n =
@ -96,7 +99,8 @@ let type_is_nested_in_direct_supertype t n =
IList.exists (is_nested_in n) (type_get_direct_supertypes t)
let rec get_type_name = function
| Sil.Tstruct (_, _, _, Some mangled, _, _, _) -> Mangled.to_string mangled
| Sil.Tstruct { Sil.struct_name = Some name } ->
Mangled.to_string name
| Sil.Tptr (t, _) -> get_type_name t
| Sil.Tvar tn -> Typename.name tn
| _ -> "_"
@ -105,12 +109,12 @@ let get_field_type_name
(typ: Sil.typ)
(fieldname: Ident.fieldname): string option =
match typ with
| Sil.Tstruct (fields, _, _, _, _, _, _)
| Sil.Tptr (Sil.Tstruct (fields, _, _, _, _, _, _), _) -> (
| Sil.Tstruct { Sil.instance_fields }
| Sil.Tptr (Sil.Tstruct { Sil.instance_fields }, _) -> (
try
let _, ft, _ = IList.find
(function | (fn, _, _) -> Ident.fieldname_equal fn fieldname)
fields in
instance_fields in
Some (get_type_name ft)
with Not_found -> None)
| _ -> None
@ -304,7 +308,7 @@ let proc_iter_overridden_methods f tenv proc_name =
let super_proc_name =
Procname.java_replace_class proc_name (Typename.name super_class_name) in
match Sil.tenv_lookup tenv super_class_name with
| Some (Sil.Tstruct (_, _, _, _, _, methods, _)) ->
| Some (Sil.Tstruct { Sil.def_methods }) ->
let is_override pname =
Procname.equal pname super_proc_name &&
not (Procname.is_constructor pname) in
@ -312,7 +316,7 @@ let proc_iter_overridden_methods f tenv proc_name =
(fun pname ->
if is_override pname
then f pname)
methods
def_methods
| _ -> () in
if Procname.is_java proc_name then

@ -118,7 +118,7 @@ let curr_class_hash curr_class =
let create_curr_class tenv class_name =
let class_tn_name = Typename.TN_csu (Csu.Class, (Mangled.from_string class_name)) in
match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct(intf_fields, _, _, _, superclasses, methods, annotation) ->
| Some Sil.Tstruct { Sil.superclasses } ->
(let superclasses_names = IList.map Typename.name superclasses in
match superclasses_names with
| superclass:: protocols ->

@ -20,10 +20,10 @@ let rec get_fields_super_classes tenv super_class =
Printing.log_out " ... Getting fields of superclass '%s'\n" (Typename.to_string super_class);
match Sil.tenv_lookup tenv super_class with
| None -> []
| Some Sil.Tstruct (fields, _, _, _, super_class :: _, _, _) ->
| Some Sil.Tstruct { Sil.instance_fields; superclasses = super_class :: _ } ->
let sc_fields = get_fields_super_classes tenv super_class in
General_utils.append_no_duplicates_fields fields sc_fields
| Some Sil.Tstruct (fields, _, _, _, _, _, _) -> fields
General_utils.append_no_duplicates_fields instance_fields sc_fields
| Some Sil.Tstruct { Sil.instance_fields } -> instance_fields
| Some _ -> []
let fields_superclass tenv interface_decl_info =
@ -79,13 +79,17 @@ let add_missing_fields tenv class_name fields =
let mang_name = Mangled.from_string class_name in
let class_tn_name = Typename.TN_csu (Csu.Class, mang_name) in
match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct(intf_fields, _, _, _, superclass, methods, annotation) ->
let new_fields = General_utils.append_no_duplicates_fields fields intf_fields in
| Some Sil.Tstruct ({ Sil.instance_fields } as struct_typ) ->
let new_fields = General_utils.append_no_duplicates_fields fields instance_fields in
let new_fields = CFrontend_utils.General_utils.sort_fields new_fields in
let class_type_info =
Sil.Tstruct (
new_fields, [], Csu.Class, Some mang_name, superclass, methods, annotation
) in
Sil.Tstruct
{ struct_typ with
Sil.instance_fields = new_fields;
static_fields = [];
csu = Csu.Class;
struct_name = Some mang_name;
} in
Printing.log_out " Updating info for class '%s' in tenv\n" class_name;
Sil.tenv_add tenv class_tn_name class_type_info
| _ -> ()

@ -43,13 +43,13 @@ let direct_atomic_property_access context stmt_info ivar_name =
let tname = Typename.TN_csu (Csu.Class, Mangled.from_string cname) in
let loc = CLocation.get_sil_location_from_range stmt_info.Clang_ast_t.si_source_range true in
match Sil.tenv_lookup tenv tname with
| Some Sil.Tstruct (flds1, flds2, _, _, _, _, _) ->
| Some Sil.Tstruct { Sil.instance_fields; static_fields } ->
(* We give the warning when:
(1) the property has the atomic attribute and
(2) the access of the ivar is not in a getter or setter method.
(3) the access of the ivar is not in the init method
Last two conditions avoids false positives *)
let condition = (CField_decl.is_ivar_atomic ivar (flds1 @ flds2))
let condition = (CField_decl.is_ivar_atomic ivar (instance_fields @ static_fields))
&& not (CContext.is_curr_proc_objc_getter context ivar)
&& not (CContext.is_curr_proc_objc_setter context ivar)
&& not (Procname.is_constructor mname)

@ -45,15 +45,16 @@ struct
match typname with
| Typename.TN_csu (Csu.Class, _) | Typename.TN_csu (Csu.Protocol, _) ->
(match typ with
| Sil.Tstruct (fields, _, _, cls, super_classes, methods, iann) ->
| Sil.Tstruct { Sil.instance_fields; superclasses; def_methods; struct_annotations } ->
print_endline (
(Typename.to_string typname) ^ " " ^ (Sil.item_annotation_to_string iann) ^ "\n" ^
(Typename.to_string typname) ^ " " ^
(Sil.item_annotation_to_string struct_annotations) ^ "\n" ^
"---> superclass and protocols " ^ (IList.to_string (fun tn ->
"\t" ^ (Typename.to_string tn) ^ "\n") super_classes) ^
"\t" ^ (Typename.to_string tn) ^ "\n") superclasses) ^
"---> methods " ^
(IList.to_string (fun x ->"\t" ^ (Procname.to_string x) ^ "\n") methods)
(IList.to_string (fun x ->"\t" ^ (Procname.to_string x) ^ "\n") def_methods)
^ " " ^
"\t---> fields " ^ (IList.to_string field_to_string fields) ^ "\n")
"\t---> fields " ^ (IList.to_string field_to_string instance_fields) ^ "\n")
| _ -> ())
| _ -> ()
) tenv
@ -63,19 +64,19 @@ struct
match typname with
| Typename.TN_csu (Csu.Struct, _) | Typename.TN_csu (Csu.Union, _) ->
(match typ with
| (Sil.Tstruct (fields, static_fields, _, cls, super_classes, methods, iann)) ->
(print_endline (
(Typename.to_string typname)^"\n"^
"\t---> fields "^(IList.to_string (fun (fieldname, typ, _) ->
match typ with
| Sil.Tvar tname -> "tvar"^(Typename.to_string tname)
| Sil.Tstruct (_, _, _, _, _, _, _) | _ ->
"\t struct "^(Ident.fieldname_to_string fieldname)^" "^
(Sil.typ_to_string typ)^"\n") fields
)
)
| Sil.Tstruct { Sil.instance_fields } ->
print_endline (
(Typename.to_string typname)^"\n"^
"\t---> fields "^(IList.to_string (fun (fieldname, typ, _) ->
match typ with
| Sil.Tvar tname -> "tvar"^(Typename.to_string tname)
| Sil.Tstruct _ | _ ->
"\t struct "^(Ident.fieldname_to_string fieldname)^" "^
(Sil.typ_to_string typ)^"\n") instance_fields
)
)
| _ -> ())
| _ -> ()
)
| Typename.TN_typedef typname ->
print_endline ((Mangled.to_string typname)^"-->"^(Sil.typ_to_string typ))
| _ -> ()

@ -191,7 +191,7 @@ let get_superclass_curr_class context =
let iname = Typename.TN_csu (Csu.Class, Mangled.from_string cname) in
Printing.log_out "Checking for superclass = '%s'\n\n%!" (Typename.to_string iname);
match Sil.tenv_lookup (CContext.get_tenv context) iname with
| Some Sil.Tstruct(_, _, _, _, super_name :: _, _, _) ->
| Some Sil.Tstruct { Sil.superclasses = super_name :: _ } ->
Typename.name super_name
| _ ->
Printing.log_err "NOT FOUND superclass = '%s'\n\n%!" (Typename.to_string iname);

@ -118,7 +118,15 @@ struct
IList.iter (fun (fn, ft, _) ->
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
let mblock = Mangled.from_string block_name in
let block_type = Sil.Tstruct (fields, [], Csu.Class, Some mblock, [], [], []) in
let block_type = Sil.Tstruct
{ Sil.instance_fields = fields;
static_fields = [];
csu = Csu.Class;
struct_name = Some mblock;
superclasses = [];
def_methods = [];
struct_annotations = [];
} in
let block_name = Typename.TN_csu (Csu.Class, mblock) in
Sil.tenv_add tenv block_name block_type;
let trans_res = CTrans_utils.alloc_trans trans_state loc (Ast_expressions.dummy_stmt_info ()) block_type true in
@ -1395,12 +1403,12 @@ struct
else
collect_left_hand_exprs e tvar (StringSet.add (Typename.to_string typename) tns)
| _ -> [[(e, typ)]] (*This case is an error, shouldn't happen.*))
| Sil.Tstruct (struct_fields, _, _, _, _, _, _) as type_struct ->
| Sil.Tstruct { Sil.instance_fields } as type_struct ->
let lh_exprs = IList.map ( fun (fieldname, fieldtype, _) ->
Sil.Lfield (e, fieldname, type_struct) )
struct_fields in
instance_fields in
let lh_types = IList.map ( fun (fieldname, fieldtype, _) -> fieldtype)
struct_fields in
instance_fields in
IList.map (fun (e, t) -> IList.flatten (collect_left_hand_exprs e t tns)) (zip lh_exprs lh_types)
| Sil.Tarray (arrtyp, Sil.Const (Sil.Cint n)) ->
let size = Sil.Int.to_int n in

@ -18,7 +18,7 @@ let get_type_from_expr_info ei =
let get_name_from_struct s =
match s with
| Sil.Tstruct(_, _, _, Some n, _, _, _) -> n
| Sil.Tstruct { Sil.struct_name = Some n } -> n
| _ -> assert false
let rec get_type_list nn ll =
@ -41,7 +41,7 @@ let remove_pointer_to_typ typ =
let classname_of_type typ =
match typ with
| Sil.Tvar (Typename.TN_csu (_, name) )
| Sil.Tstruct(_, _, _, (Some name), _, _, _)
| Sil.Tstruct { Sil.struct_name = Some name }
| Sil.Tvar (Typename.TN_typedef name) -> Mangled.to_string name
| Sil.Tfun _ -> CFrontend_config.objc_object
| _ ->
@ -73,8 +73,8 @@ let mk_enumname n = Typename.TN_enum (Mangled.from_string n)
let is_class typ =
match typ with
| Sil.Tptr( Sil.Tstruct(_, _, _, (Some name), _, _, _), _)
| Sil.Tptr( Sil.Tvar (Typename.TN_csu (_, name) ), _) ->
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _)
| Sil.Tptr (Sil.Tvar (Typename.TN_csu (_, name) ), _) ->
(Mangled.to_string name) = CFrontend_config.objc_class
| _ -> false

@ -19,8 +19,15 @@ let add_predefined_objc_types tenv =
let objc_class_mangled = Mangled.from_string CFrontend_config.objc_class in
let objc_class_name = Typename.TN_csu (Csu.Class, objc_class_mangled) in
let objc_class_type_info =
Sil.Tstruct ([], [], Csu.Struct,
Some (Mangled.from_string CFrontend_config.objc_class), [], [], []) in
Sil.Tstruct {
Sil.instance_fields = [];
static_fields = [];
csu = Csu.Struct;
struct_name = Some (Mangled.from_string CFrontend_config.objc_class);
superclasses = [];
def_methods = [];
struct_annotations = [];
} in
Sil.tenv_add tenv objc_class_name objc_class_type_info;
let class_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCClass in
let class_typ = Sil.Tvar (Typename.TN_csu (Csu.Struct, objc_class_mangled)) in
@ -31,8 +38,15 @@ let add_predefined_objc_types tenv =
let id_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCId in
Sil.tenv_add tenv id_typename id_typedef;
let objc_object_type_info =
Sil.Tstruct ([], [], Csu.Struct,
Some (Mangled.from_string CFrontend_config.objc_object), [], [], []) in
Sil.Tstruct {
Sil.instance_fields = [];
static_fields = [];
csu = Csu.Struct;
struct_name = Some (Mangled.from_string CFrontend_config.objc_object);
superclasses = [];
def_methods = [];
struct_annotations = [];
} in
Sil.tenv_add tenv typename_objc_object objc_object_type_info
(* Whenever new type are added manually to the translation in ast_expressions, *)
@ -134,7 +148,7 @@ let get_superclass_list decl =
let add_struct_to_tenv tenv typ =
let csu = match typ with
| Sil.Tstruct(_, _, csu, _, _, _, _) -> csu
| Sil.Tstruct { Sil.csu } -> csu
| _ -> assert false in
let mangled = CTypes.get_name_from_struct typ in
let typename = Typename.TN_csu(csu, mangled) in
@ -179,13 +193,20 @@ and get_struct_cpp_class_declaration_type tenv decl =
else non_static_fields in
let sorted_non_static_fields = CFrontend_utils.General_utils.sort_fields non_static_fields' in
let static_fields = [] in (* Warning for the moment we do not treat static field. *)
let methods = get_class_methods tenv name decl_list in (* C++ methods only *)
let def_methods = get_class_methods tenv name decl_list in (* C++ methods only *)
let superclasses = get_superclass_list decl in
let item_annotation =
let struct_annotations =
if csu = Csu.Class then Sil.cpp_class_annotation
else Sil.item_annotation_empty in (* No annotations for structs *)
let sil_type = Sil.Tstruct (sorted_non_static_fields, static_fields, csu,
Some mangled_name, superclasses, methods, item_annotation) in
let sil_type = Sil.Tstruct
{ Sil.instance_fields = sorted_non_static_fields;
static_fields;
csu;
struct_name = Some mangled_name;
superclasses;
def_methods;
struct_annotations;
} in
Ast_utils.update_sil_types_map type_ptr sil_type;
add_struct_to_tenv tenv sil_type;
sil_type

@ -77,14 +77,20 @@ let process_category type_ptr_to_sil_type tenv curr_class decl_info decl_list =
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar class_tn_name);
(match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct (intf_fields, _, _, _, superclass, intf_methods, annotation) ->
let new_fields = General_utils.append_no_duplicates_fields fields intf_fields in
| Some Sil.Tstruct
({ Sil.instance_fields; def_methods }
as struct_typ) ->
let new_fields = General_utils.append_no_duplicates_fields fields instance_fields in
let new_fields = CFrontend_utils.General_utils.sort_fields new_fields in
let new_methods = General_utils.append_no_duplicates_methods methods intf_methods in
let new_methods = General_utils.append_no_duplicates_methods methods def_methods in
let class_type_info =
Sil.Tstruct (
new_fields, [], Csu.Class, Some mang_name, superclass, new_methods, annotation
) in
Sil.Tstruct { struct_typ with
Sil.instance_fields = new_fields;
static_fields = [];
csu = Csu.Class;
struct_name = Some mang_name;
def_methods = new_methods;
} in
Printing.log_out " Updating info for class '%s' in tenv\n" class_name;
Sil.tenv_add tenv class_tn_name class_type_info
| _ -> ());

@ -114,10 +114,10 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name
(*In case we found categories, or partial definition of this class earlier and they are already in the tenv *)
let fields, (superclasses : Typename.t list), methods =
match Sil.tenv_lookup tenv interface_name with
| Some (Sil.Tstruct (saved_fields, _, _, _, saved_superclasses, saved_methods, _)) ->
General_utils.append_no_duplicates_fields fields saved_fields,
General_utils.append_no_duplicates_csu superclasses saved_superclasses,
General_utils.append_no_duplicates_methods methods saved_methods
| Some (Sil.Tstruct { Sil.instance_fields; superclasses; def_methods }) ->
General_utils.append_no_duplicates_fields fields instance_fields,
General_utils.append_no_duplicates_csu superclasses superclasses,
General_utils.append_no_duplicates_methods methods def_methods
| _ -> fields, superclasses, methods in
let fields = General_utils.append_no_duplicates_fields fields fields_sc in
(* We add the special hidden counter_field for implementing reference counting *)
@ -127,8 +127,15 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name
IList.iter (fun (fn, ft, _) ->
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
let interface_type_info =
Sil.Tstruct(fields, [], Csu.Class, Some (Mangled.from_string class_name),
superclasses, methods, Sil.objc_class_annotation) in
Sil.Tstruct {
Sil.instance_fields = fields;
static_fields = [];
csu = Csu.Class;
struct_name = Some (Mangled.from_string class_name);
superclasses;
def_methods = methods;
struct_annotations = Sil.objc_class_annotation;
} in
Sil.tenv_add tenv interface_name interface_type_info;
Printing.log_out
" >>>Verifying that Typename '%s' is in tenv\n" (Typename.to_string interface_name);
@ -143,11 +150,17 @@ let add_missing_methods tenv class_name decl_info decl_list curr_class =
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar class_tn_name);
(match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct (fields, [], Csu.Class, Some name,
superclass, existing_methods, annotation) ->
let methods = General_utils.append_no_duplicates_methods existing_methods methods in
| Some Sil.Tstruct
({ Sil.static_fields = [];
csu = Csu.Class;
struct_name = Some name;
def_methods;
} as struct_typ) ->
let methods = General_utils.append_no_duplicates_methods def_methods methods in
let typ =
Sil.Tstruct (fields, [], Csu.Class, Some name, superclass, methods, annotation) in
Sil.Tstruct
{ struct_typ with
Sil.def_methods = methods; } in
Sil.tenv_add tenv class_tn_name typ
| _ -> ());
Sil.Tvar class_tn_name

@ -31,9 +31,17 @@ let protocol_decl type_ptr_to_sil_type tenv decl =
let protocol_name = Typename.TN_csu (Csu.Protocol, mang_name) in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar protocol_name);
let methods = ObjcProperty_decl.get_methods curr_class decl_list in
let def_methods = ObjcProperty_decl.get_methods curr_class decl_list in
let protocol_type_info =
Sil.Tstruct ([], [], Csu.Protocol, Some mang_name, [], methods, []) in
Sil.Tstruct {
Sil.instance_fields = [];
static_fields = [];
csu = Csu.Protocol;
struct_name = Some mang_name;
superclasses = [];
def_methods;
struct_annotations = [];
} in
Sil.tenv_add tenv protocol_name protocol_type_info;
add_protocol_super type_ptr_to_sil_type tenv obj_c_protocol_decl_info;
Sil.Tvar protocol_name

@ -134,7 +134,7 @@ let check_condition case_zero find_canonical_duplicate get_proc_desc curr_pname
let throwable_found = ref false in
let throwable_class = Mangled.from_string "java.lang.Throwable" in
let typ_is_throwable = function
| Sil.Tstruct (_, _, Csu.Class, Some c, _, _, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c } ->
Mangled.equal c throwable_class
| _ -> false in
let do_instr = function
@ -253,8 +253,8 @@ let check_constructor_initialization
if Procname.is_constructor curr_pname
then begin
match PatternMatch.get_this_type (Cfg.Procdesc.get_attributes curr_pdesc) with
| Some (Sil.Tptr (Sil.Tstruct (ftal, _, _, nameo, _, _, _) as ts, _)) ->
let do_fta (fn, ft, ia) =
| Some (Sil.Tptr (Sil.Tstruct { Sil.instance_fields; struct_name } as ts, _)) ->
let do_field (fn, ft, ia) =
let annotated_with f = match get_field_annotation fn ts with
| None -> false
| Some (_, ia) -> f ia in
@ -289,7 +289,7 @@ let check_constructor_initialization
let should_check_field =
let in_current_class =
let fld_cname = Ident.java_fieldname_get_class fn in
match nameo with
match struct_name with
| None -> false
| Some name -> Mangled.equal name (Mangled.from_string fld_cname) in
not inject_annotated &&
@ -325,7 +325,7 @@ let check_constructor_initialization
curr_pname;
end in
IList.iter do_fta ftal
IList.iter do_field instance_fields
| _ -> ()
end

@ -253,7 +253,8 @@ let android_callbacks =
(* TODO (t4644852): factor out subtyping functions into some sort of JavaUtil module *)
let get_all_supertypes typ tenv =
let get_direct_supers = function
| Sil.Tstruct (_, _, Csu.Class, _, supers, _, _) -> supers
| Sil.Tstruct { Sil.csu = Csu.Class; superclasses } ->
superclasses
| _ -> [] in
let rec add_typ class_name typs =
match Sil.tenv_lookup tenv class_name with
@ -295,7 +296,7 @@ let is_callback_class_name class_name = Mangled.MangledSet.mem class_name androi
let is_callback_class typ tenv =
let supertyps = get_all_supertypes typ tenv in
TypSet.exists (fun typ -> match typ with
| Sil.Tstruct (_, _, Csu.Class, Some classname, _, _, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some classname } ->
is_callback_class_name classname
| _ -> false) supertyps
@ -356,12 +357,13 @@ let is_callback_register_method procname args tenv =
a list of method names [lifecycle_procs_strs], get the appropriate typ and procnames *)
let get_lifecycle_for_framework_typ_opt lifecycle_typ lifecycle_proc_strs tenv =
match Sil.tenv_lookup tenv (Typename.TN_csu (Csu.Class, lifecycle_typ)) with
| Some (Sil.Tstruct(_, _, Csu.Class, Some class_name, _, decl_procs, _) as lifecycle_typ) ->
| Some (Sil.Tstruct
{ Sil.csu = Csu.Class; struct_name = Some _; def_methods } as lifecycle_typ) ->
(* TODO (t4645631): collect the procedures for which is_java is returning false *)
let lookup_proc lifecycle_proc =
IList.find (fun decl_proc ->
Procname.is_java decl_proc && lifecycle_proc = Procname.java_get_method decl_proc
) decl_procs in
) def_methods in
(* convert each of the framework lifecycle proc strings to a lifecycle method procname *)
let lifecycle_procs =
IList.fold_left (fun lifecycle_procs lifecycle_proc_str ->

@ -118,7 +118,7 @@ let find_registered_callbacks lifecycle_trace harness_name proc_file_map tenv =
(** if [typ] is a lifecycle type, generate a list of (method call, receiver) pairs constituting a
lifecycle trace *)
let try_create_lifecycle_trace typ lifecycle_typ lifecycle_procs proc_file_map tenv = match typ with
| Sil.Tstruct(_, _, Csu.Class, Some name, _, methods, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some name } ->
let class_name = Typename.TN_csu (Csu.Class, name) in
if AndroidFramework.typ_is_lifecycle_typ typ lifecycle_typ tenv &&
not (AndroidFramework.is_android_lib_class class_name) then
@ -143,7 +143,15 @@ let extract_callbacks lifecycle_trace harness_procname proc_file_map tenv =
let fields = IList.map (fun (fld, typ, _) -> (fld, typ, [])) registered_cbs in
(* create a new typ for the harness containing all of the cb extraction vars as static fields *)
let harness_typ =
Sil.Tstruct (fields, [], Csu.Class, Some harness_name, [], [harness_procname], []) in
Sil.Tstruct {
Sil.instance_fields = fields;
static_fields = [];
csu = Csu.Class;
struct_name = Some harness_name;
superclasses = [];
def_methods = [harness_procname];
struct_annotations = [];
} in
(* update the tenv with our created harness typ. we don't have to save the tenv to disk here
* because this is done immediately after harness generation runs in jMain.ml *)
let harness_class = Typename.TN_csu (Csu.Class, harness_name) in

@ -108,14 +108,14 @@ let rec inhabit_typ typ proc_file_map env =
(* select methods that are constructors and won't force us into infinite recursion because
* we are already inhabiting one of their argument types *)
let get_all_suitable_constructors typ = match typ with
| Sil.Tstruct (_, _, Csu.Class, _, superclasses, methods, _) ->
| Sil.Tstruct { Sil.csu = Csu.Class; def_methods } ->
let is_suitable_constructor p =
let try_get_non_receiver_formals p =
try get_non_receiver_formals (formals_from_name p proc_file_map)
with Not_found -> [] in
Procname.is_constructor p && IList.for_all (fun (_, typ) ->
not (TypSet.mem typ env.cur_inhabiting)) (try_get_non_receiver_formals p) in
IList.filter (fun p -> is_suitable_constructor p) methods
IList.filter (fun p -> is_suitable_constructor p) def_methods
| _ -> [] in
let (env, typ_class_name) = match get_all_suitable_constructors typ with
| constructor :: _ ->
@ -205,7 +205,7 @@ let inhabit_fld_trace flds proc_file_map env =
Sil.Letderef (lhs, fld_exp, fld_typ, env.pc) in
let env = env_add_instr fld_read_instr [lhs] env in
match fld_typ with
| Sil.Tptr (Sil.Tstruct (_, _, Csu.Class, _, _, procs, _), _) ->
| Sil.Tptr (Sil.Tstruct { Sil.csu = Csu.Class; def_methods }, _) ->
let inhabit_cb_call procname env =
try
let procdesc = procdesc_from_name procname proc_file_map in
@ -220,7 +220,7 @@ let inhabit_fld_trace flds proc_file_map env =
IList.fold_left (fun env procname ->
if not (Procname.is_constructor procname) &&
not (Procname.java_is_access_method procname) then inhabit_cb_call procname env
else env) env procs
else env) env def_methods
| _ -> assert false in
IList.fold_left (fun env fld -> invoke_cb fld env) env flds

@ -43,11 +43,11 @@ let try_resolve_frame str_frame exe_env tenv =
* in the stack trace. Note that the stack trace does not have any type or argument information;
* the name is all that we have to go on *)
match Sil.tenv_lookup tenv (Typename.TN_csu (Csu.Class, class_name)) with
| Some Sil.Tstruct (_, _, Csu.Class, _, _, decl_procs, _) ->
| Some Sil.Tstruct { Sil.csu = Csu.Class; def_methods } ->
let possible_calls =
IList.filter
(fun proc -> Procname.java_get_method proc = str_frame.method_str)
decl_procs in
def_methods in
if IList.length possible_calls > 0 then
(* using IList.hd here assumes that all of the possible calls are declared in the
* same file, which will be true in Java but not necessarily in other languages *)

@ -107,12 +107,12 @@ let retrieve_fieldname fieldname =
let get_field_name program static tenv cn fs context =
match JTransType.get_class_type_no_pointer program tenv cn with
| Sil.Tstruct (fields, sfields, Csu.Class, _, _, _, _) ->
| Sil.Tstruct { Sil.instance_fields; static_fields; csu = Csu.Class } ->
let fieldname, _, _ =
try
IList.find
(fun (fieldname, _, _) -> retrieve_fieldname fieldname = JBasics.fs_name fs)
(if static then sfields else fields)
(if static then static_fields else instance_fields)
with Not_found ->
(* TODO: understand why fields cannot be found here *)
JUtils.log "cannot find %s.%s@." (JBasics.cn_name cn) (JBasics.fs_name fs);

@ -91,7 +91,8 @@ let rec create_array_type typ dim =
let extract_cn_no_obj typ =
match typ with
| Sil.Tptr (Sil.Tstruct (_, _, Csu.Class, Some classname, _, _, _), Sil.Pk_pointer) ->
| Sil.Tptr (Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some classname },
Sil.Pk_pointer) ->
let class_name = (Mangled.to_string classname) in
if class_name = JConfig.object_cl then None
else
@ -239,7 +240,15 @@ let collect_interface_field cn inf l =
let dummy_type cn =
let classname = Mangled.from_string (JBasics.cn_name cn) in
Sil.Tstruct ([], [], Csu.Class, Some classname, [], [], Sil.item_annotation_empty)
Sil.Tstruct {
Sil.instance_fields = [];
static_fields = [];
csu = Csu.Class;
struct_name = Some classname;
superclasses = [];
def_methods = [];
struct_annotations = Sil.item_annotation_empty;
}
let collect_models_class_fields classpath_field_map cn cf fields =
@ -283,7 +292,7 @@ let add_model_fields program classpath_fields cn =
let rec get_all_fields program tenv cn =
let extract_class_fields classname =
match get_class_type_no_pointer program tenv classname with
| Sil.Tstruct (nonstatic, static, _, _, _, _, _) -> (static, nonstatic)
| Sil.Tstruct { Sil.instance_fields; static_fields } -> (static_fields, instance_fields)
| _ -> assert false in
let trans_fields classname =
match JClasspath.lookup_node classname program with
@ -307,7 +316,7 @@ and create_sil_type program tenv cn =
| Some node ->
let create_super_list interface_names =
IList.map typename_of_classname interface_names in
let (super_list, nonstatic_fields, static_fields, item_annotation) =
let superclasses, instance_fields, static_fields, struct_annotations =
match node with
| Javalib.JInterface jinterface ->
let static_fields, _ = get_all_fields program tenv cn in
@ -326,15 +335,22 @@ and create_sil_type program tenv cn =
| Some super_cn ->
let super_classname =
match get_class_type_no_pointer program tenv super_cn with
| Sil.Tstruct (_, _, _, Some classname, _, _, _) ->
| Sil.Tstruct { Sil.struct_name = Some classname } ->
Typename.TN_csu (Csu.Class, classname)
| _ -> assert false in
super_classname :: interface_list in
(super_classname_list, nonstatic_fields, static_fields, item_annotation) in
let classname = Mangled.from_string (JBasics.cn_name cn) in
let method_procnames = get_class_procnames cn node in
Sil.Tstruct (nonstatic_fields, static_fields, Csu.Class,
Some classname, super_list, method_procnames, item_annotation)
let def_methods = get_class_procnames cn node in
Sil.Tstruct {
Sil.instance_fields;
static_fields;
csu = Csu.Class;
struct_name = Some classname;
superclasses;
def_methods;
struct_annotations;
}
and get_class_type_no_pointer program tenv cn =

Loading…
Cancel
Save