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 (match typ with
| Sil.Tvar _ -> assert false (* there should be no indirection *) | Sil.Tvar _ -> assert false (* there should be no indirection *)
| Sil.Tint _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tfloat _ | Sil.Tenum _ -> [] | 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.Tarray _ -> [])
| Sil.Var _ -> [] (* type of |-> not known yet *) | Sil.Var _ -> [] (* type of |-> not known yet *)
| Sil.Const _ -> [] | Sil.Const _ -> []
@ -769,9 +770,9 @@ let is_simply_recursive tenv tname =
assert false (* there should be no indirection *) assert false (* there should be no indirection *)
| Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tenum _ -> | Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tenum _ ->
None None
| Sil.Tstruct (fld_typ_ann_list, _, _, _, _, _, _) -> | Sil.Tstruct { Sil.instance_fields } ->
begin begin
match (IList.filter filter fld_typ_ann_list) with match (IList.filter filter instance_fields) with
| [(fld, _, _)] -> Some fld | [(fld, _, _)] -> Some fld
| _ -> None | _ -> None
end end
@ -1192,10 +1193,11 @@ let cycle_has_weak_or_unretained_or_assign_field cycle =
(* returns items annotation for field fn in struct t *) (* returns items annotation for field fn in struct t *)
let get_item_annotation t fn = let get_item_annotation t fn =
match t with match t with
| Sil.Tstruct(nsf, sf, _, _, _, _, _) -> | Sil.Tstruct { Sil.instance_fields; static_fields } ->
let ia = ref [] in let ia = ref [] in
IList.iter (fun (fn', t', ia') -> 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 !ia
| _ -> [] in | _ -> [] in
let rec has_weak_or_unretained_or_assign params = 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 = let rec get_strexp_at_syn_offsets se t syn_offs =
match se, t, syn_offs with match se, t, syn_offs with
| _, _, [] -> (se, t) | _, _, [] -> (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 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' get_strexp_at_syn_offsets se' t' syn_offs'
| Sil.Earray (size, esel, _), Sil.Tarray(t', _), Index ind :: 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 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 match se, t, syn_offs with
| _, _, [] -> | _, _, [] ->
update se t 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 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 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 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) Sil.Estruct (fsel', inst)
@ -142,8 +146,8 @@ end = struct
if pred sigma_other (path, se, typ) then found := (sigma, hpred, offs') :: !found if pred sigma_other (path, se, typ) then found := (sigma, hpred, offs') :: !found
else begin else begin
match se, typ with match se, typ with
| Sil.Estruct (fsel, _), Sil.Tstruct (ftal, sftal, _, _, _, _, _) -> | Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields } ->
find_offset_fsel sigma_other hpred root offs fsel ftal typ find_offset_fsel sigma_other hpred root offs fsel instance_fields typ
| Sil.Earray (size, esel, _), Sil.Tarray (t, _) -> | Sil.Earray (size, esel, _), Sil.Tarray (t, _) ->
find_offset_esel sigma_other hpred root offs esel 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 let rec do_se se typ = match se, typ with
| Sil.Eexp (e, inst), _ -> | Sil.Eexp (e, inst), _ ->
do_exp e typ do_exp e typ
| Sil.Estruct (fsel, _), Sil.Tstruct (ftal, sftal, _, _, _, _, _) -> | Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields } ->
do_struct fsel ftal do_struct fsel instance_fields
| Sil.Earray (size, esel, _), Sil.Tarray (typ, size') -> | Sil.Earray (size, esel, _), Sil.Tarray (typ, size') ->
do_se (Sil.Eexp (size, Sil.inst_none)) (Sil.Tint Sil.IULong); do_se (Sil.Eexp (size, Sil.inst_none)) (Sil.Tint Sil.IULong);
do_array esel typ do_array esel typ
@ -419,9 +419,10 @@ let pp_texp_for_malloc fmt =
typ typ
| Sil.Tptr (t, pk) -> | Sil.Tptr (t, pk) ->
Sil.Tptr (handle_arr_size t, pk) Sil.Tptr (handle_arr_size t, pk)
| Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) -> | Sil.Tstruct struct_typ ->
Sil.Tstruct (IList.map (fun (f, t, a) -> let instance_fields =
(f, handle_arr_size t, a)) ftal, sftal, csu, nameo, supers, def_mthds, iann) 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 (t, e) ->
Sil.Tarray (handle_arr_size t, e) in Sil.Tarray (handle_arr_size t, e) in
function function

@ -542,9 +542,12 @@ let vpath_find prop _exp : Sil.dexp option * Sil.typ option =
(match lexp with (match lexp with
| Sil.Lvar pv -> | Sil.Lvar pv ->
let typo = match texp with let typo = match texp with
| Sil.Sizeof (Sil.Tstruct (ftl, ftal, _, _, _, _, _), _) -> | Sil.Sizeof (Sil.Tstruct struct_typ, _) ->
(try (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 Some t
with Not_found -> None) with Not_found -> None)
| _ -> None in | _ -> 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 s, " to ", " on " in
let typ_str = let typ_str =
match hpred_type_opt with 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 -> when !Config.curr_language = Config.Java ->
" of type " ^ Mangled.to_string classname ^ " " " of type " ^ Mangled.to_string classname ^ " "
| _ -> " " in | _ -> " " in

@ -209,7 +209,7 @@ struct
| Sil.Tptr (styp, _ ) -> | Sil.Tptr (styp, _ ) ->
is_core_lib lib styp is_core_lib lib styp
| Sil.Tvar (Typename.TN_csu (_, name) ) | 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 let core_lib_types = core_lib_to_type_list lib in
IList.mem (=) (Mangled.to_string name) core_lib_types IList.mem (=) (Mangled.to_string name) core_lib_types
| _ -> false | _ -> false

@ -598,21 +598,23 @@ let sym_eval abs e =
eval (Sil.BinOp (Sil.PlusPI, e11, e2')) eval (Sil.BinOp (Sil.PlusPI, e11, e2'))
| Sil.BinOp | Sil.BinOp
(Sil.PlusA, (Sil.PlusA,
(Sil.Sizeof (Sil.Sizeof (Sil.Tstruct struct_typ, st) as e1),
(Sil.Tstruct (ftal, sftal, csu, name_opt, supers, def_mthds, iann), st) as e1),
e2) -> e2) ->
(* pattern for extensible structs given a struct declatead as struct s { ... t arr[n] ... }, (* 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 allocation pattern malloc(sizeof(struct s) + k * siezof(t)) turn it into
struct s { ... t arr[n + k] ... } *) struct s { ... t arr[n + k] ... } *)
let e1' = eval e1 in let e1' = eval e1 in
let e2' = eval e2 in let e2' = eval e2 in
(match IList.rev ftal, e2' with let instance_fields = struct_typ.Sil.instance_fields in
(fname, Sil.Tarray(typ, size), _):: ltfa, Sil.BinOp(Sil.Mult, num_elem, Sil.Sizeof (texp, st)) when ftal != [] && Sil.typ_equal typ texp -> (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 size' = Sil.BinOp(Sil.PlusA, size, num_elem) in
let ltfa' = (fname, Sil.Tarray(typ, size'), Sil.item_annotation_empty) :: ltfa in let ltfa' = (fname, Sil.Tarray(typ, size'), Sil.item_annotation_empty) :: ltfa in
Sil.Sizeof let struct_typ' =
(Sil.Tstruct { struct_typ with Sil.instance_fields = ltfa' } in
(IList.rev ltfa', sftal, csu, name_opt, supers, def_mthds, iann), st) Sil.Sizeof (Sil.Tstruct struct_typ', st)
| _ -> Sil.BinOp(Sil.PlusA, e1', e2')) | _ -> Sil.BinOp(Sil.PlusA, e1', e2'))
| Sil.BinOp (Sil.PlusA as oplus, e1, e2) | Sil.BinOp (Sil.PlusA as oplus, e1, e2)
| Sil.BinOp (Sil.PlusPI 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 typ
| Sil.Tptr (t', pk) -> | Sil.Tptr (t', pk) ->
Sil.Tptr (typ_normalize sub 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 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 (t, e) ->
Sil.Tarray (typ_normalize sub t, exp_normalize sub e) Sil.Tarray (typ_normalize sub t, exp_normalize sub e)
| Sil.Tenum econsts -> | Sil.Tenum econsts ->
@ -1119,7 +1127,7 @@ let rec create_strexp_of_type tenvo struct_init_mode typ inst =
match typ with match typ with
| Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tenum _ -> | Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tenum _ ->
Sil.Eexp (init_value (), inst) Sil.Eexp (init_value (), inst)
| Sil.Tstruct (ftal, sftal, _, _, _, _, _) -> | Sil.Tstruct { Sil.instance_fields } ->
begin begin
match struct_init_mode with match struct_init_mode with
| No_init -> Sil.Estruct ([], inst) | 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)) (fld, Sil.Eexp (Sil.exp_one, inst))
else else
(fld, create_strexp_of_type tenvo struct_init_mode t inst) in (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 end
| Sil.Tarray (_, size) -> | Sil.Tarray (_, size) ->
Sil.Earray (size, [], inst) Sil.Earray (size, [], inst)
@ -1661,15 +1669,15 @@ let sigma_intro_nonemptylseg e1 e2 sigma =
f (hpred :: sigma_passed) sigma' f (hpred :: sigma_passed) sigma'
| Sil.Hlseg (Sil.Lseg_PE, para, f1, f2, shared) :: sigma' | Sil.Hlseg (Sil.Lseg_PE, para, f1, f2, shared) :: sigma'
when (Sil.exp_equal e1 f1 && Sil.exp_equal e2 f2) 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' f (Sil.Hlseg (Sil.Lseg_NE, para, f1, f2, shared) :: sigma_passed) sigma'
| Sil.Hlseg _ as hpred :: sigma' -> | Sil.Hlseg _ as hpred :: sigma' ->
f (hpred :: sigma_passed) sigma' f (hpred :: sigma_passed) sigma'
| Sil.Hdllseg (Sil.Lseg_PE, para, iF, oB, oF, iB, shared) :: sigma' | Sil.Hdllseg (Sil.Lseg_PE, para, iF, oB, oF, iB, shared) :: sigma'
when (Sil.exp_equal e1 iF && Sil.exp_equal e2 oF) when (Sil.exp_equal e1 iF && Sil.exp_equal e2 oF)
|| (Sil.exp_equal e2 iF && Sil.exp_equal e1 oF) || (Sil.exp_equal e2 iF && Sil.exp_equal e1 oF)
|| (Sil.exp_equal e1 iB && Sil.exp_equal e2 oB) || (Sil.exp_equal e1 iB && Sil.exp_equal e2 oB)
|| (Sil.exp_equal e2 iB && Sil.exp_equal e1 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' f (Sil.Hdllseg (Sil.Lseg_NE, para, iF, oB, oF, iB, shared) :: sigma_passed) sigma'
| Sil.Hdllseg _ as hpred :: sigma' -> | Sil.Hdllseg _ as hpred :: sigma' ->
f (hpred :: sigma_passed) 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 -> | e1, Sil.Var v2 ->
let occurs_check v e = (* check whether [v] occurs in normalized [e] *) let occurs_check v e = (* check whether [v] occurs in normalized [e] *)
if Sil.fav_mem (Sil.exp_fav e) v 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 then raise (IMPL_EXC ("occurs check", subs, (EXC_FALSE_EXPS (e1, e2)))) in
if Ident.is_primed v2 then if Ident.is_primed v2 then
let () = occurs_check v2 e1 in 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 let t' = match t, typ_fld with
| _, Sil.Tstruct _ -> (* the struct type of fld is known *) | _, Sil.Tstruct _ -> (* the struct type of fld is known *)
Sil.Sizeof (typ_fld, Sil.Subtype.exact) 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.Sizeof
(Sil.Tstruct (Sil.Tstruct
([(fld, _t, Sil.item_annotation_empty)], { Sil.instance_fields = [(fld, t1, Sil.item_annotation_empty)];
[], Csu.Struct, None, [], [], Sil.item_annotation_empty), st) 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 *) (* None as we don't know the stuct name *)
| _ -> raise (Failure "expand_hpred_pointer: Unexpected non-sizeof type in Lfield") in | _ -> 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 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 = let is_interface tenv class_name =
match Sil.tenv_lookup tenv class_name with match Sil.tenv_lookup tenv class_name with
| Some (Sil.Tstruct (fields, sfields, Csu.Class, Some c1', supers1, methods, iann)) -> | Some (Sil.Tstruct ( { Sil.csu = Csu.Class; struct_name = Some _ } as struct_typ )) ->
(IList.length fields = 0) && (IList.length methods = 0) (IList.length struct_typ.Sil.instance_fields = 0) &&
(IList.length struct_typ.Sil.def_methods = 0)
| _ -> false | _ -> false
(** check if c1 is a subclass of c2 *) (** check if c1 is a subclass of c2 *)
@ -1457,8 +1464,8 @@ let check_subclass_tenv tenv c1 c2 =
let rec check cn = let rec check cn =
Typename.equal cn c2 || Typename.equal c2 object_type || Typename.equal cn c2 || Typename.equal c2 object_type ||
match Sil.tenv_lookup tenv cn with match Sil.tenv_lookup tenv cn with
| Some (Sil.Tstruct (_, _, Csu.Class, Some c1', supers1, _, _)) -> | Some (Sil.Tstruct { Sil.struct_name = Some _; csu = Csu.Class; superclasses }) ->
IList.exists check supers1 IList.exists check superclasses
| _ -> false in | _ -> false in
check c1 check c1
@ -1478,8 +1485,8 @@ let check_subtype_basic_type t1 t2 =
(** check if t1 is a subtype of t2 *) (** check if t1 is a subtype of t2 *)
let rec check_subtype tenv t1 t2 = let rec check_subtype tenv t1 t2 =
match t1, t2 with match t1, t2 with
| Sil.Tstruct (_, _, Csu.Class, Some c1, _, _, _), | Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c1 },
Sil.Tstruct (_, _, Csu.Class, Some c2, _, _, _) -> Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c2 } ->
let cn1 = Typename.TN_csu (Csu.Class, c1) let cn1 = Typename.TN_csu (Csu.Class, c1)
and cn2 = Typename.TN_csu (Csu.Class, c2) in and cn2 = Typename.TN_csu (Csu.Class, c2) in
(check_subclass tenv cn1 cn2) (check_subclass tenv cn1 cn2)
@ -1490,7 +1497,7 @@ let rec check_subtype tenv t1 t2 =
| Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) -> | Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) ->
check_subtype tenv dom_type1 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 let cn2 = Typename.TN_csu (Csu.Class, c2) in
Typename.equal cn2 serializable_type Typename.equal cn2 serializable_type
|| Typename.equal cn2 cloneable_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) = let rec case_analysis_type tenv (t1, st1) (t2, st2) =
match t1, t2 with match t1, t2 with
| Sil.Tstruct (_, _, Csu.Class, Some c1, _, _, _), | Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c1 },
Sil.Tstruct (_, _, Csu.Class, Some c2, _, _, _) -> Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some c2 } ->
let cn1 = Typename.TN_csu (Csu.Class, c1) let cn1 = Typename.TN_csu (Csu.Class, c1)
and cn2 = Typename.TN_csu (Csu.Class, c2) in and cn2 = Typename.TN_csu (Csu.Class, c2) in
(Sil.Subtype.case_analysis (cn1, st1) (cn2, st2) (check_subclass tenv) (is_interface tenv)) (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, _) -> | Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) ->
(case_analysis_type tenv (dom_type1, st1) (dom_type2, st2)) (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 let cn1 = Typename.TN_csu (Csu.Class, c1) in
if (Typename.equal cn1 serializable_type if (Typename.equal cn1 serializable_type
|| Typename.equal cn1 cloneable_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 Ident.create kind !max_stamp in
let res = let res =
match t, off with match t, off with
| Sil.Tstruct (ftal, sftal, _, _, _, _, _),[] -> | Sil.Tstruct _, [] ->
([], Sil.Estruct ([], inst), t) ([], 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' -> (Sil.Off_fld (f, _)):: off' ->
let _, t', _ = let _, t', _ =
try 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 -> with Not_found ->
raise (Exceptions.Bad_footprint (try assert false with Assert_failure x -> x)) in raise (Exceptions.Bad_footprint (try assert false with Assert_failure x -> x)) in
let atoms', se', res_t' = 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 pname tenv orig_prop footprint_part kind max_stamp t' off' inst in
let se = Sil.Estruct ([(f, se')], 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 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 let instance_fields' =
(atoms', se, Sil.Tstruct (ftal', sftal, csu, nameo, supers, def_mthds, iann)) 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' -> | Sil.Tstruct _, (Sil.Off_index e):: off' ->
let atoms', se', res_t' = let atoms', se', res_t' =
create_struct_values create_struct_values
@ -200,11 +202,12 @@ let rec _strexp_extend_values
_strexp_extend_values _strexp_extend_values
pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
| (Sil.Off_fld (f, _)):: off', Sil.Estruct (fsel, 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 replace_fv new_v fv = if Ident.fieldname_equal (fst fv) f then (f, new_v) else fv in
let _, typ', _ = let _, typ', _ =
try 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 -> with Not_found ->
raise (Exceptions.Missing_fld (f, try assert false with Assert_failure x -> x)) in raise (Exceptions.Missing_fld (f, try assert false with Assert_failure x -> x)) in
begin begin
@ -217,9 +220,10 @@ let rec _strexp_extend_values
let replace_fse = replace_fv res_se' in let replace_fse = replace_fv res_se' in
let res_fsel' = IList.sort Sil.fld_strexp_compare (IList.map replace_fse fsel) 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 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 = 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 (res_atoms', Sil.Estruct (res_fsel', inst'), struct_typ) :: acc in
IList.fold_left replace [] atoms_se_typ_list' IList.fold_left replace [] atoms_se_typ_list'
with Not_found -> 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 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 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 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 instance_fields' =
let struct_typ = Sil.Tstruct (res_ftl', sftal, csu, nameo, supers, def_mthds, iann) in 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)] [(atoms', Sil.Estruct (res_fsel', inst'), struct_typ)]
end end
| (Sil.Off_fld (f, _)):: off', _, _ -> | (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 type_at_offset texp off =
let rec strip_offset off typ = match off, typ with let rec strip_offset off typ = match off, typ with
| [], _ -> Some typ | [], _ -> Some typ
| (Sil.Off_fld (f, _)):: off', Sil.Tstruct (ftal, sftal, _, _, _, _, _) -> | (Sil.Off_fld (f, _)):: off', Sil.Tstruct { Sil.instance_fields } ->
(try (try
let typ' = let typ' =
(fun (x, y, z) -> y) (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' strip_offset off' typ'
with Not_found -> None) with Not_found -> None)
| (Sil.Off_index _):: off', Sil.Tarray (typ', _) -> | (Sil.Off_index _):: off', Sil.Tarray (typ', _) ->

@ -648,6 +648,17 @@ and const =
and struct_fields = (Ident.fieldname * typ * item_annotation) list 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 *) (** types for sil (structured) expressions *)
and typ = and typ =
| Tvar of Typename.t (** named type *) | Tvar of Typename.t (** named type *)
@ -656,12 +667,7 @@ and typ =
| Tvoid (** void type *) | Tvoid (** void type *)
| Tfun of bool (** function type with noreturn attribute *) | Tfun of bool (** function type with noreturn attribute *)
| Tptr of typ * ptr_kind (** pointer type *) | Tptr of typ * ptr_kind (** pointer type *)
| Tstruct of struct_fields * struct_fields * Csu.t * Mangled.t option * | Tstruct of struct_typ (** Type for a structured value *)
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. *)
| Tarray of typ * exp (** array type with fixed size *) | Tarray of typ * exp (** array type with fixed size *)
| Tenum of (Mangled.t * const) list | 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 = let has_objc_ref_counter hpred =
match hpred with match hpred with
| Hpointsto(_, _, Sizeof(Tstruct(fl, _, _, _, _, _, _), _)) -> | Hpointsto(_, _, Sizeof(Tstruct struct_typ, _)) ->
IList.exists is_objc_ref_counter_field fl IList.exists is_objc_ref_counter_field struct_typ.instance_fields
| _ -> false | _ -> false
let objc_class_str = "ObjC-Class" let objc_class_str = "ObjC-Class"
@ -847,8 +853,8 @@ let cpp_class_annotation =
let is_class_of_language typ class_string = let is_class_of_language typ class_string =
match typ with match typ with
| Tstruct(_, _, Csu.Class, _, _, _, a) -> | Tstruct { csu = Csu.Class; struct_annotations } ->
(match a with (match struct_annotations with
| [({ class_name = n; parameters = []}, true)] | [({ class_name = n; parameters = []}, true)]
when n = class_string -> true when n = class_string -> true
| _ -> false) | _ -> false)
@ -1288,6 +1294,13 @@ let rec const_compare (c1 : const) (c2 : const) : int =
| _, Cptr_to_fld _ -> 1 | _, Cptr_to_fld _ -> 1
| Ctuple el1, Ctuple el2 -> IList.compare exp_compare el1 el2 | 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. *) (** Comparision for types. *)
and typ_compare t1 t2 = and typ_compare t1 t2 =
if t1 == t2 then 0 else match t1, t2 with 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 if n <> 0 then n else ptr_kind_compare pk1 pk2
| Tptr _, _ -> - 1 | Tptr _, _ -> - 1
| _, Tptr _ -> 1 | _, Tptr _ -> 1
| Tstruct (ntal1, sntal1, csu1, nameo1, _, _, _), | Tstruct struct_typ1, Tstruct struct_typ2 ->
Tstruct (ntal2, sntal2, csu2, nameo2, _, _, _) -> struct_typ_compare struct_typ1 struct_typ2
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 _, _ -> - 1 | Tstruct _, _ -> - 1
| _, Tstruct _ -> 1 | _, Tstruct _ -> 1
| Tarray (t1, _), Tarray (t2, _) -> typ_compare t1 t2 | 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) -> | Tptr (typ, pk) ->
let pp_base' fmt () = F.fprintf fmt "%s%a" (ptr_kind_string pk) pp_base () in 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 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 *) (* 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) -> (pp_seq (fun f (fld, t, ann) ->
F.fprintf f "%a %a" (pp_typ_full pe) t Ident.pp_fieldname fld)) F.fprintf f "%a %a"
ftal pp_base () (pp_typ_full pe) t
| Tstruct (ftal, sftal, csu, Some name, _, _, _) -> Ident.pp_fieldname fld)) struct_typ.instance_fields
F.fprintf f "%s %a %a" (Csu.name csu) Mangled.pp name pp_base () 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 ()
| Tarray (typ, size) -> | Tarray (typ, size) ->
let pp_base' fmt () = F.fprintf fmt "%a[%a]" pp_base () (pp_size pe) size in 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 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) -> | Tptr (t', pk) ->
typ_iter_types f t' typ_iter_types f t'
| Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) -> | Tstruct struct_typ ->
IList.iter (fun (_, t, _) -> typ_iter_types f t) ftal IList.iter (fun (_, t, _) -> typ_iter_types f t) struct_typ.instance_fields
| Tarray (t, e) -> | Tarray (t, e) ->
typ_iter_types f t; typ_iter_types f t;
exp_iter_types f e exp_iter_types f e
@ -2814,8 +2835,10 @@ let texp_to_typ default_opt = function
let struct_typ_fld default_opt f = let struct_typ_fld default_opt f =
let def () = unsome_typ "struct_typ_fld" default_opt in let def () = unsome_typ "struct_typ_fld" default_opt in
function function
| Tstruct (ftal, sftal, _, _, _, _, _) -> | Tstruct struct_typ ->
(try (fun (x, y, z) -> y) (IList.find (fun (_f, t, ann) -> Ident.fieldname_equal _f f) ftal) (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 ()) with Not_found -> def ())
| _ -> def () | _ -> def ()

@ -279,6 +279,17 @@ and const =
and struct_fields = (Ident.fieldname * typ * item_annotation) list 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. *) (** Types for sil (structured) expressions. *)
and typ = and typ =
| Tvar of Typename.t (** named type *) | Tvar of Typename.t (** named type *)
@ -287,12 +298,7 @@ and typ =
| Tvoid (** void type *) | Tvoid (** void type *)
| Tfun of bool (** function type with noreturn attribute *) | Tfun of bool (** function type with noreturn attribute *)
| Tptr of typ * ptr_kind (** pointer type *) | Tptr of typ * ptr_kind (** pointer type *)
| Tstruct of struct_fields * struct_fields * Csu.t * Mangled.t option * | Tstruct of struct_typ (** Type for a structured value *)
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. *)
| Tarray of typ * exp (** array type with fixed size *) | Tarray of typ * exp (** array type with fixed size *)
| Tenum of (Mangled.t * const) list | Tenum of (Mangled.t * const) list

@ -42,9 +42,9 @@ let rec unroll_type tenv typ off =
| Sil.Tvar _, _ -> | Sil.Tvar _, _ ->
let typ' = Sil.expand_type tenv typ in let typ' = Sil.expand_type tenv typ in
unroll_type tenv typ' off 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 begin
try fldlist_assoc fld (ftal @ sftal) try fldlist_assoc fld (instance_fields @ static_fields)
with Not_found -> with Not_found ->
L.d_strln ".... Invalid Field Access ...."; L.d_strln ".... Invalid Field Access ....";
L.d_strln ("Fld : " ^ Ident.fieldname_to_string fld); 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') -> | (Sil.Off_fld (fld, fld_typ)):: offlist', Sil.Estruct (fsel, inst') ->
begin begin
let typ' = Sil.expand_type tenv typ in let typ' = Sil.expand_type tenv typ in
let ftal, sftal, csu, nameo, supers, def_mthds, iann = let struct_typ =
match typ' with match typ' with
| Sil.Tstruct (ftal, sftal, csu, nameo, supers, def_mthds, iann) -> | Sil.Tstruct struct_typ ->
ftal, sftal, csu, nameo, supers, def_mthds, iann struct_typ
| _ -> assert false in | _ -> assert false in
let t' = unroll_type tenv typ (Sil.Off_fld (fld, fld_typ)) in let t' = unroll_type tenv typ (Sil.Off_fld (fld, fld_typ)) in
try 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 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 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 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 = let res_t =
Sil.Tstruct Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in
(IList.map replace_fta ftal, sftal, csu, nameo, supers, def_mthds, iann) in
(res_e', res_se, res_t, res_pred_insts_op') (res_e', res_se, res_t, res_pred_insts_op')
with Not_found -> with Not_found ->
pp_error(); pp_error();
@ -606,11 +606,11 @@ let resolve_method tenv class_name proc_name =
Procname.java_replace_class proc_name (Typename.name class_name) Procname.java_replace_class proc_name (Typename.name class_name)
else Procname.c_method_replace_class proc_name (Typename.name class_name) in else Procname.c_method_replace_class proc_name (Typename.name class_name) in
match Sil.tenv_lookup tenv class_name with match Sil.tenv_lookup tenv class_name with
| Some (Sil.Tstruct (_, _, Csu.Class, cls, super_classes, methods, iann)) -> | Some (Sil.Tstruct { Sil.csu = Csu.Class; def_methods; superclasses }) ->
if method_exists right_proc_name methods then if method_exists right_proc_name def_methods then
Some right_proc_name Some right_proc_name
else else
(match super_classes with (match superclasses with
| super_classname:: interfaces -> | super_classname:: interfaces ->
if not (Typename.Set.mem super_classname !visited) if not (Typename.Set.mem super_classname !visited)
then resolve super_classname then resolve super_classname
@ -634,8 +634,8 @@ let resolve_typename prop arg =
| _ :: hpreds -> loop hpreds in | _ :: hpreds -> loop hpreds in
loop (Prop.get_sigma prop) in loop (Prop.get_sigma prop) in
match typexp_opt with match typexp_opt with
| Some (Sil.Sizeof (Sil.Tstruct (_, _, _, None, _, _, _), _)) -> None | Some (Sil.Sizeof (Sil.Tstruct { Sil.struct_name = None }, _)) -> None
| Some (Sil.Sizeof (Sil.Tstruct (_, _, Csu.Class, Some name, _, _, _), _)) -> | Some (Sil.Sizeof (Sil.Tstruct { Sil.csu = Csu.Class; struct_name = Some name }, _)) ->
Some (Typename.TN_csu (Csu.Class, name)) Some (Typename.TN_csu (Csu.Class, name))
| _ -> None | _ -> 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 redirect_shared_ptr tenv cfg pname actual_params =
let class_shared_ptr typ = let class_shared_ptr typ =
try match Sil.expand_type tenv typ with 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 let name = Mangled.to_string cl_name in
name = "shared_ptr" || name = "__shared_ptr" name = "shared_ptr" || name = "__shared_ptr"
| t -> false | 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 | _, [id] -> Errdesc.id_is_assigned_then_dead (State.get_node ()) id
| _ -> false in | _ -> false in
if is_ignored 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 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 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 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' | 0 -> ftal_sub ftal1' ftal2'
| _ -> ftal_sub ftal1 ftal2' end in | _ -> ftal_sub ftal1 ftal2' end in
let typ_star t1 t2 = match t1, t2 with let typ_star t1 t2 = match t1, t2 with
| Sil.Tstruct (ftal1, sftal1, csu1, _, _, _, _), | Sil.Tstruct { Sil.instance_fields = instance_fields1; csu = csu1 },
Sil.Tstruct (ftal2, sftal2, csu2, _, _, _, _) when csu1 = csu2 -> Sil.Tstruct { Sil.instance_fields = instance_fields2; csu = csu2 } when csu1 = csu2 ->
if ftal_sub ftal1 ftal2 then t2 else t1 if ftal_sub instance_fields1 instance_fields2 then t2 else t1
| _ -> t1 in | _ -> t1 in
match texp1, texp2 with match texp1, texp2 with
| Sil.Sizeof (t1, st1), Sil.Sizeof (t2, st2) -> Sil.Sizeof (typ_star t1 t2, Sil.Subtype.join st1 st2) | 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 exn_name = ref (Typename.Java.from_string "") in
let find_exn_name e = let find_exn_name e =
let do_hpred = function 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 let found_exn_name = Typename.TN_csu (Csu.Class, name) in
exn_name := found_exn_name exn_name := found_exn_name
| _ -> () in | _ -> () in

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

@ -37,10 +37,12 @@ let suppressLint = "android.annotation.SuppressLint"
let get_field_type_and_annotation fn = function let get_field_type_and_annotation fn = function
| Sil.Tptr (Sil.Tstruct (ftal, sftal, _, _, _, _, _), _) | Sil.Tptr (Sil.Tstruct struct_typ, _)
| Sil.Tstruct (ftal, sftal, _, _, _, _, _) -> | Sil.Tstruct struct_typ ->
(try (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) Some (t, a)
with Not_found -> None) with Not_found -> None)
| _ -> None | _ -> None

@ -83,7 +83,7 @@ let callback_checker_main all_procs get_procdesc idenv tenv proc_name proc_desc
let typename = let typename =
Typename.TN_csu (Csu.Class, Mangled.from_string (Procname.java_get_class proc_name)) in Typename.TN_csu (Csu.Class, Mangled.from_string (Procname.java_get_class proc_name)) in
match Sil.tenv_lookup tenv typename with 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 lifecycle_typs = get_or_create_lifecycle_typs tenv in
let proc_belongs_to_lifecycle_typ = IList.exists let proc_belongs_to_lifecycle_typ = IList.exists
(fun lifecycle_typ -> AndroidFramework.typ_is_lifecycle_typ typ lifecycle_typ tenv) (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 let registered_callback_procs' = IList.fold_left
(fun callback_procs callback_typ -> (fun callback_procs callback_typ ->
match callback_typ with 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 IList.fold_left
(fun callback_procs callback_proc -> (fun callback_procs callback_proc ->
if Procname.is_constructor callback_proc then callback_procs if Procname.is_constructor callback_proc then callback_procs
else Procname.Set.add callback_proc callback_procs) else Procname.Set.add callback_proc callback_procs)
callback_procs callback_procs
methods def_methods'
| typ -> callback_procs) | typ -> callback_procs)
!registered_callback_procs !registered_callback_procs
registered_callback_typs in 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 *) (* compute the set of fields nullified by this procedure *)
(* TODO (t4959422): get fields that are nullified in callees of the destroy method *) (* 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 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 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 PatternMatch.has_formal_method_argument_type_names proc_desc proc_name ["android.os.Parcel"] in
let parcel_constructors = function let parcel_constructors = function
| Sil.Tptr (Sil.Tstruct (_, _, _, _, _, methods, _), _) -> | Sil.Tptr (Sil.Tstruct { Sil.def_methods }, _) ->
IList.filter is_parcel_constructor methods IList.filter is_parcel_constructor def_methods
| _ -> [] in | _ -> [] in
let check r_name r_desc w_name w_desc = 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 object_name = Mangled.from_string "java.lang.Object"
let type_is_object = function 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 | _ -> false
let java_proc_name_with_class_method pn class_with_path method_name = 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 = let is_direct_subtype_of this_type super_type_name =
match this_type with match this_type with
| Sil.Tptr (Sil.Tstruct (_, _, _, _, supertypes, _, _), _) -> | Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _) ->
IList.exists (fun cn -> Typename.equal cn super_type_name) supertypes IList.exists (fun cn -> Typename.equal cn super_type_name) superclasses
| _ -> false | _ -> false
(** The type the method is invoked on *) (** The type the method is invoked on *)
@ -37,12 +38,13 @@ let get_this_type proc_attributes = match proc_attributes.ProcAttributes.formals
| _ -> None | _ -> None
let type_get_direct_supertypes = function let type_get_direct_supertypes = function
| Sil.Tptr (Sil.Tstruct (_, _, _, _, supertypes, _, _), _) | Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _)
| Sil.Tstruct (_, _, _, _, supertypes, _, _) -> supertypes | Sil.Tstruct { Sil.superclasses } ->
superclasses
| _ -> [] | _ -> []
let type_get_class_name t = match t with 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 Some cn
| Sil.Tptr (Sil.Tvar (Typename.TN_csu (Csu.Class, cn)), _) -> | Sil.Tptr (Sil.Tvar (Typename.TN_csu (Csu.Class, cn)), _) ->
Some cn Some cn
@ -51,8 +53,9 @@ let type_get_class_name t = match t with
let type_get_annotation let type_get_annotation
(t: Sil.typ): Sil.item_annotation option = (t: Sil.typ): Sil.item_annotation option =
match t with match t with
| Sil.Tptr (Sil.Tstruct (_, _, _, _, _, _, ia), _) | Sil.Tptr (Sil.Tstruct { Sil.struct_annotations }, _)
| Sil.Tstruct (_, _, _, _, _, _, ia) -> Some ia | Sil.Tstruct { Sil.struct_annotations } ->
Some struct_annotations
| _ -> None | _ -> None
let type_has_class_name t name = let type_has_class_name t name =
@ -71,8 +74,8 @@ let type_has_supertype
else else
begin begin
match Sil.expand_type tenv typ with match Sil.expand_type tenv typ with
| Sil.Tptr (Sil.Tstruct (_, _, _, _, supertypes, _, _), _) | Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _)
| Sil.Tstruct (_, _, _, _, supertypes, _, _) -> | Sil.Tstruct { Sil.superclasses } ->
let match_supertype cn = let match_supertype cn =
let match_name () = Typename.equal cn class_name in let match_name () = Typename.equal cn class_name in
let has_indirect_supertype () = let has_indirect_supertype () =
@ -80,15 +83,15 @@ let type_has_supertype
| Some supertype -> has_supertype supertype (Sil.TypSet.add typ visited) | Some supertype -> has_supertype supertype (Sil.TypSet.add typ visited)
| None -> false in | None -> false in
(match_name () || has_indirect_supertype ()) in (match_name () || has_indirect_supertype ()) in
IList.exists match_supertype supertypes IList.exists match_supertype superclasses
| _ -> false | _ -> false
end in end in
has_supertype typ Sil.TypSet.empty has_supertype typ Sil.TypSet.empty
let type_is_nested_in_type t n = match t with let type_is_nested_in_type t n = match t with
| Sil.Tptr (Sil.Tstruct (_, _, _, Some m, _, _, _), _) -> | Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _) ->
string_is_prefix (Mangled.to_string n ^ "$") (Mangled.to_string m) string_is_prefix (Mangled.to_string n ^ "$") (Mangled.to_string name)
| _ -> false | _ -> false
let type_is_nested_in_direct_supertype t n = 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) IList.exists (is_nested_in n) (type_get_direct_supertypes t)
let rec get_type_name = function 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.Tptr (t, _) -> get_type_name t
| Sil.Tvar tn -> Typename.name tn | Sil.Tvar tn -> Typename.name tn
| _ -> "_" | _ -> "_"
@ -105,12 +109,12 @@ let get_field_type_name
(typ: Sil.typ) (typ: Sil.typ)
(fieldname: Ident.fieldname): string option = (fieldname: Ident.fieldname): string option =
match typ with match typ with
| Sil.Tstruct (fields, _, _, _, _, _, _) | Sil.Tstruct { Sil.instance_fields }
| Sil.Tptr (Sil.Tstruct (fields, _, _, _, _, _, _), _) -> ( | Sil.Tptr (Sil.Tstruct { Sil.instance_fields }, _) -> (
try try
let _, ft, _ = IList.find let _, ft, _ = IList.find
(function | (fn, _, _) -> Ident.fieldname_equal fn fieldname) (function | (fn, _, _) -> Ident.fieldname_equal fn fieldname)
fields in instance_fields in
Some (get_type_name ft) Some (get_type_name ft)
with Not_found -> None) with Not_found -> None)
| _ -> None | _ -> None
@ -304,7 +308,7 @@ let proc_iter_overridden_methods f tenv proc_name =
let super_proc_name = let super_proc_name =
Procname.java_replace_class proc_name (Typename.name super_class_name) in Procname.java_replace_class proc_name (Typename.name super_class_name) in
match Sil.tenv_lookup tenv super_class_name with match Sil.tenv_lookup tenv super_class_name with
| Some (Sil.Tstruct (_, _, _, _, _, methods, _)) -> | Some (Sil.Tstruct { Sil.def_methods }) ->
let is_override pname = let is_override pname =
Procname.equal pname super_proc_name && Procname.equal pname super_proc_name &&
not (Procname.is_constructor pname) in not (Procname.is_constructor pname) in
@ -312,7 +316,7 @@ let proc_iter_overridden_methods f tenv proc_name =
(fun pname -> (fun pname ->
if is_override pname if is_override pname
then f pname) then f pname)
methods def_methods
| _ -> () in | _ -> () in
if Procname.is_java proc_name then 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 create_curr_class tenv class_name =
let class_tn_name = Typename.TN_csu (Csu.Class, (Mangled.from_string class_name)) in let class_tn_name = Typename.TN_csu (Csu.Class, (Mangled.from_string class_name)) in
match Sil.tenv_lookup tenv class_tn_name with 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 (let superclasses_names = IList.map Typename.name superclasses in
match superclasses_names with match superclasses_names with
| superclass:: protocols -> | 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); Printing.log_out " ... Getting fields of superclass '%s'\n" (Typename.to_string super_class);
match Sil.tenv_lookup tenv super_class with match Sil.tenv_lookup tenv super_class with
| None -> [] | 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 let sc_fields = get_fields_super_classes tenv super_class in
General_utils.append_no_duplicates_fields fields sc_fields General_utils.append_no_duplicates_fields instance_fields sc_fields
| Some Sil.Tstruct (fields, _, _, _, _, _, _) -> fields | Some Sil.Tstruct { Sil.instance_fields } -> instance_fields
| Some _ -> [] | Some _ -> []
let fields_superclass tenv interface_decl_info = 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 mang_name = Mangled.from_string class_name in
let class_tn_name = Typename.TN_csu (Csu.Class, mang_name) in let class_tn_name = Typename.TN_csu (Csu.Class, mang_name) in
match Sil.tenv_lookup tenv class_tn_name with match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct(intf_fields, _, _, _, superclass, methods, annotation) -> | Some Sil.Tstruct ({ Sil.instance_fields } as struct_typ) ->
let new_fields = General_utils.append_no_duplicates_fields fields intf_fields in 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_fields = CFrontend_utils.General_utils.sort_fields new_fields in
let class_type_info = let class_type_info =
Sil.Tstruct ( Sil.Tstruct
new_fields, [], Csu.Class, Some mang_name, superclass, methods, annotation { struct_typ with
) in 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; Printing.log_out " Updating info for class '%s' in tenv\n" class_name;
Sil.tenv_add tenv class_tn_name class_type_info 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 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 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 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: (* We give the warning when:
(1) the property has the atomic attribute and (1) the property has the atomic attribute and
(2) the access of the ivar is not in a getter or setter method. (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 (3) the access of the ivar is not in the init method
Last two conditions avoids false positives *) 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_getter context ivar)
&& not (CContext.is_curr_proc_objc_setter context ivar) && not (CContext.is_curr_proc_objc_setter context ivar)
&& not (Procname.is_constructor mname) && not (Procname.is_constructor mname)

@ -45,15 +45,16 @@ struct
match typname with match typname with
| Typename.TN_csu (Csu.Class, _) | Typename.TN_csu (Csu.Protocol, _) -> | Typename.TN_csu (Csu.Class, _) | Typename.TN_csu (Csu.Protocol, _) ->
(match typ with (match typ with
| Sil.Tstruct (fields, _, _, cls, super_classes, methods, iann) -> | Sil.Tstruct { Sil.instance_fields; superclasses; def_methods; struct_annotations } ->
print_endline ( 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 -> "---> superclass and protocols " ^ (IList.to_string (fun tn ->
"\t" ^ (Typename.to_string tn) ^ "\n") super_classes) ^ "\t" ^ (Typename.to_string tn) ^ "\n") superclasses) ^
"---> methods " ^ "---> 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 ) tenv
@ -63,19 +64,19 @@ struct
match typname with match typname with
| Typename.TN_csu (Csu.Struct, _) | Typename.TN_csu (Csu.Union, _) -> | Typename.TN_csu (Csu.Struct, _) | Typename.TN_csu (Csu.Union, _) ->
(match typ with (match typ with
| (Sil.Tstruct (fields, static_fields, _, cls, super_classes, methods, iann)) -> | Sil.Tstruct { Sil.instance_fields } ->
(print_endline ( print_endline (
(Typename.to_string typname)^"\n"^ (Typename.to_string typname)^"\n"^
"\t---> fields "^(IList.to_string (fun (fieldname, typ, _) -> "\t---> fields "^(IList.to_string (fun (fieldname, typ, _) ->
match typ with match typ with
| Sil.Tvar tname -> "tvar"^(Typename.to_string tname) | Sil.Tvar tname -> "tvar"^(Typename.to_string tname)
| Sil.Tstruct (_, _, _, _, _, _, _) | _ -> | Sil.Tstruct _ | _ ->
"\t struct "^(Ident.fieldname_to_string fieldname)^" "^ "\t struct "^(Ident.fieldname_to_string fieldname)^" "^
(Sil.typ_to_string typ)^"\n") fields (Sil.typ_to_string typ)^"\n") instance_fields
) )
)
) )
| _ -> ()) | _ -> ()
)
| Typename.TN_typedef typname -> | Typename.TN_typedef typname ->
print_endline ((Mangled.to_string typname)^"-->"^(Sil.typ_to_string typ)) 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 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); Printing.log_out "Checking for superclass = '%s'\n\n%!" (Typename.to_string iname);
match Sil.tenv_lookup (CContext.get_tenv context) iname with 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 Typename.name super_name
| _ -> | _ ->
Printing.log_err "NOT FOUND superclass = '%s'\n\n%!" (Typename.to_string iname); Printing.log_err "NOT FOUND superclass = '%s'\n\n%!" (Typename.to_string iname);

@ -118,7 +118,15 @@ struct
IList.iter (fun (fn, ft, _) -> IList.iter (fun (fn, ft, _) ->
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields; Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
let mblock = Mangled.from_string block_name in 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 let block_name = Typename.TN_csu (Csu.Class, mblock) in
Sil.tenv_add tenv block_name block_type; 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 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 else
collect_left_hand_exprs e tvar (StringSet.add (Typename.to_string typename) tns) collect_left_hand_exprs e tvar (StringSet.add (Typename.to_string typename) tns)
| _ -> [[(e, typ)]] (*This case is an error, shouldn't happen.*)) | _ -> [[(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, _) -> let lh_exprs = IList.map ( fun (fieldname, fieldtype, _) ->
Sil.Lfield (e, fieldname, type_struct) ) Sil.Lfield (e, fieldname, type_struct) )
struct_fields in instance_fields in
let lh_types = IList.map ( fun (fieldname, fieldtype, _) -> fieldtype) 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) 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)) -> | Sil.Tarray (arrtyp, Sil.Const (Sil.Cint n)) ->
let size = Sil.Int.to_int n in 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 = let get_name_from_struct s =
match s with match s with
| Sil.Tstruct(_, _, _, Some n, _, _, _) -> n | Sil.Tstruct { Sil.struct_name = Some n } -> n
| _ -> assert false | _ -> assert false
let rec get_type_list nn ll = let rec get_type_list nn ll =
@ -41,7 +41,7 @@ let remove_pointer_to_typ typ =
let classname_of_type typ = let classname_of_type typ =
match typ with match typ with
| Sil.Tvar (Typename.TN_csu (_, name) ) | 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.Tvar (Typename.TN_typedef name) -> Mangled.to_string name
| Sil.Tfun _ -> CFrontend_config.objc_object | 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 = let is_class typ =
match typ with match typ with
| Sil.Tptr( Sil.Tstruct(_, _, _, (Some name), _, _, _), _) | Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _)
| Sil.Tptr( Sil.Tvar (Typename.TN_csu (_, name) ), _) -> | Sil.Tptr (Sil.Tvar (Typename.TN_csu (_, name) ), _) ->
(Mangled.to_string name) = CFrontend_config.objc_class (Mangled.to_string name) = CFrontend_config.objc_class
| _ -> false | _ -> 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_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_name = Typename.TN_csu (Csu.Class, objc_class_mangled) in
let objc_class_type_info = let objc_class_type_info =
Sil.Tstruct ([], [], Csu.Struct, Sil.Tstruct {
Some (Mangled.from_string CFrontend_config.objc_class), [], [], []) in 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; 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_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 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 let id_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCId in
Sil.tenv_add tenv id_typename id_typedef; Sil.tenv_add tenv id_typename id_typedef;
let objc_object_type_info = let objc_object_type_info =
Sil.Tstruct ([], [], Csu.Struct, Sil.Tstruct {
Some (Mangled.from_string CFrontend_config.objc_object), [], [], []) in 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 Sil.tenv_add tenv typename_objc_object objc_object_type_info
(* Whenever new type are added manually to the translation in ast_expressions, *) (* 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 add_struct_to_tenv tenv typ =
let csu = match typ with let csu = match typ with
| Sil.Tstruct(_, _, csu, _, _, _, _) -> csu | Sil.Tstruct { Sil.csu } -> csu
| _ -> assert false in | _ -> assert false in
let mangled = CTypes.get_name_from_struct typ in let mangled = CTypes.get_name_from_struct typ in
let typename = Typename.TN_csu(csu, mangled) 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 else non_static_fields in
let sorted_non_static_fields = CFrontend_utils.General_utils.sort_fields 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 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 superclasses = get_superclass_list decl in
let item_annotation = let struct_annotations =
if csu = Csu.Class then Sil.cpp_class_annotation if csu = Csu.Class then Sil.cpp_class_annotation
else Sil.item_annotation_empty in (* No annotations for structs *) else Sil.item_annotation_empty in (* No annotations for structs *)
let sil_type = Sil.Tstruct (sorted_non_static_fields, static_fields, csu, let sil_type = Sil.Tstruct
Some mangled_name, superclasses, methods, item_annotation) in { 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; Ast_utils.update_sil_types_map type_ptr sil_type;
add_struct_to_tenv tenv sil_type; add_struct_to_tenv tenv sil_type;
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 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); Ast_utils.update_sil_types_map decl_key (Sil.Tvar class_tn_name);
(match Sil.tenv_lookup tenv class_tn_name with (match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct (intf_fields, _, _, _, superclass, intf_methods, annotation) -> | Some Sil.Tstruct
let new_fields = General_utils.append_no_duplicates_fields fields intf_fields in ({ 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_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 = let class_type_info =
Sil.Tstruct ( Sil.Tstruct { struct_typ with
new_fields, [], Csu.Class, Some mang_name, superclass, new_methods, annotation Sil.instance_fields = new_fields;
) in 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; Printing.log_out " Updating info for class '%s' in tenv\n" class_name;
Sil.tenv_add tenv class_tn_name class_type_info 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 *) (*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 = let fields, (superclasses : Typename.t list), methods =
match Sil.tenv_lookup tenv interface_name with match Sil.tenv_lookup tenv interface_name with
| Some (Sil.Tstruct (saved_fields, _, _, _, saved_superclasses, saved_methods, _)) -> | Some (Sil.Tstruct { Sil.instance_fields; superclasses; def_methods }) ->
General_utils.append_no_duplicates_fields fields saved_fields, General_utils.append_no_duplicates_fields fields instance_fields,
General_utils.append_no_duplicates_csu superclasses saved_superclasses, General_utils.append_no_duplicates_csu superclasses superclasses,
General_utils.append_no_duplicates_methods methods saved_methods General_utils.append_no_duplicates_methods methods def_methods
| _ -> fields, superclasses, methods in | _ -> fields, superclasses, methods in
let fields = General_utils.append_no_duplicates_fields fields fields_sc in let fields = General_utils.append_no_duplicates_fields fields fields_sc in
(* We add the special hidden counter_field for implementing reference counting *) (* 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, _) -> IList.iter (fun (fn, ft, _) ->
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields; Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
let interface_type_info = let interface_type_info =
Sil.Tstruct(fields, [], Csu.Class, Some (Mangled.from_string class_name), Sil.Tstruct {
superclasses, methods, Sil.objc_class_annotation) in 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; Sil.tenv_add tenv interface_name interface_type_info;
Printing.log_out Printing.log_out
" >>>Verifying that Typename '%s' is in tenv\n" (Typename.to_string interface_name); " >>>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 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); Ast_utils.update_sil_types_map decl_key (Sil.Tvar class_tn_name);
(match Sil.tenv_lookup tenv class_tn_name with (match Sil.tenv_lookup tenv class_tn_name with
| Some Sil.Tstruct (fields, [], Csu.Class, Some name, | Some Sil.Tstruct
superclass, existing_methods, annotation) -> ({ Sil.static_fields = [];
let methods = General_utils.append_no_duplicates_methods existing_methods methods in 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 = 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.tenv_add tenv class_tn_name typ
| _ -> ()); | _ -> ());
Sil.Tvar class_tn_name 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 protocol_name = Typename.TN_csu (Csu.Protocol, mang_name) in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer 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); 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 = 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; Sil.tenv_add tenv protocol_name protocol_type_info;
add_protocol_super type_ptr_to_sil_type tenv obj_c_protocol_decl_info; add_protocol_super type_ptr_to_sil_type tenv obj_c_protocol_decl_info;
Sil.Tvar protocol_name 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_found = ref false in
let throwable_class = Mangled.from_string "java.lang.Throwable" in let throwable_class = Mangled.from_string "java.lang.Throwable" in
let typ_is_throwable = function 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 Mangled.equal c throwable_class
| _ -> false in | _ -> false in
let do_instr = function let do_instr = function
@ -253,8 +253,8 @@ let check_constructor_initialization
if Procname.is_constructor curr_pname if Procname.is_constructor curr_pname
then begin then begin
match PatternMatch.get_this_type (Cfg.Procdesc.get_attributes curr_pdesc) with match PatternMatch.get_this_type (Cfg.Procdesc.get_attributes curr_pdesc) with
| Some (Sil.Tptr (Sil.Tstruct (ftal, _, _, nameo, _, _, _) as ts, _)) -> | Some (Sil.Tptr (Sil.Tstruct { Sil.instance_fields; struct_name } as ts, _)) ->
let do_fta (fn, ft, ia) = let do_field (fn, ft, ia) =
let annotated_with f = match get_field_annotation fn ts with let annotated_with f = match get_field_annotation fn ts with
| None -> false | None -> false
| Some (_, ia) -> f ia in | Some (_, ia) -> f ia in
@ -289,7 +289,7 @@ let check_constructor_initialization
let should_check_field = let should_check_field =
let in_current_class = let in_current_class =
let fld_cname = Ident.java_fieldname_get_class fn in let fld_cname = Ident.java_fieldname_get_class fn in
match nameo with match struct_name with
| None -> false | None -> false
| Some name -> Mangled.equal name (Mangled.from_string fld_cname) in | Some name -> Mangled.equal name (Mangled.from_string fld_cname) in
not inject_annotated && not inject_annotated &&
@ -325,7 +325,7 @@ let check_constructor_initialization
curr_pname; curr_pname;
end in end in
IList.iter do_fta ftal IList.iter do_field instance_fields
| _ -> () | _ -> ()
end end

@ -253,7 +253,8 @@ let android_callbacks =
(* TODO (t4644852): factor out subtyping functions into some sort of JavaUtil module *) (* TODO (t4644852): factor out subtyping functions into some sort of JavaUtil module *)
let get_all_supertypes typ tenv = let get_all_supertypes typ tenv =
let get_direct_supers = function let get_direct_supers = function
| Sil.Tstruct (_, _, Csu.Class, _, supers, _, _) -> supers | Sil.Tstruct { Sil.csu = Csu.Class; superclasses } ->
superclasses
| _ -> [] in | _ -> [] in
let rec add_typ class_name typs = let rec add_typ class_name typs =
match Sil.tenv_lookup tenv class_name with 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 is_callback_class typ tenv =
let supertyps = get_all_supertypes typ tenv in let supertyps = get_all_supertypes typ tenv in
TypSet.exists (fun typ -> match typ with 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 is_callback_class_name classname
| _ -> false) supertyps | _ -> 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 *) 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 = 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 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 *) (* TODO (t4645631): collect the procedures for which is_java is returning false *)
let lookup_proc lifecycle_proc = let lookup_proc lifecycle_proc =
IList.find (fun decl_proc -> IList.find (fun decl_proc ->
Procname.is_java decl_proc && lifecycle_proc = Procname.java_get_method 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 *) (* convert each of the framework lifecycle proc strings to a lifecycle method procname *)
let lifecycle_procs = let lifecycle_procs =
IList.fold_left (fun lifecycle_procs lifecycle_proc_str -> 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 (** if [typ] is a lifecycle type, generate a list of (method call, receiver) pairs constituting a
lifecycle trace *) lifecycle trace *)
let try_create_lifecycle_trace typ lifecycle_typ lifecycle_procs proc_file_map tenv = match typ with 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 let class_name = Typename.TN_csu (Csu.Class, name) in
if AndroidFramework.typ_is_lifecycle_typ typ lifecycle_typ tenv && if AndroidFramework.typ_is_lifecycle_typ typ lifecycle_typ tenv &&
not (AndroidFramework.is_android_lib_class class_name) then 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 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 *) (* create a new typ for the harness containing all of the cb extraction vars as static fields *)
let harness_typ = 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 (* 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 *) * because this is done immediately after harness generation runs in jMain.ml *)
let harness_class = Typename.TN_csu (Csu.Class, harness_name) in 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 (* select methods that are constructors and won't force us into infinite recursion because
* we are already inhabiting one of their argument types *) * we are already inhabiting one of their argument types *)
let get_all_suitable_constructors typ = match typ with 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 is_suitable_constructor p =
let try_get_non_receiver_formals p = let try_get_non_receiver_formals p =
try get_non_receiver_formals (formals_from_name p proc_file_map) try get_non_receiver_formals (formals_from_name p proc_file_map)
with Not_found -> [] in with Not_found -> [] in
Procname.is_constructor p && IList.for_all (fun (_, typ) -> Procname.is_constructor p && IList.for_all (fun (_, typ) ->
not (TypSet.mem typ env.cur_inhabiting)) (try_get_non_receiver_formals p) in 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 | _ -> [] in
let (env, typ_class_name) = match get_all_suitable_constructors typ with let (env, typ_class_name) = match get_all_suitable_constructors typ with
| constructor :: _ -> | constructor :: _ ->
@ -205,7 +205,7 @@ let inhabit_fld_trace flds proc_file_map env =
Sil.Letderef (lhs, fld_exp, fld_typ, env.pc) in Sil.Letderef (lhs, fld_exp, fld_typ, env.pc) in
let env = env_add_instr fld_read_instr [lhs] env in let env = env_add_instr fld_read_instr [lhs] env in
match fld_typ with 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 = let inhabit_cb_call procname env =
try try
let procdesc = procdesc_from_name procname proc_file_map in 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 -> IList.fold_left (fun env procname ->
if not (Procname.is_constructor procname) && if not (Procname.is_constructor procname) &&
not (Procname.java_is_access_method procname) then inhabit_cb_call procname env 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 | _ -> assert false in
IList.fold_left (fun env fld -> invoke_cb fld env) env flds 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; * 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 *) * the name is all that we have to go on *)
match Sil.tenv_lookup tenv (Typename.TN_csu (Csu.Class, class_name)) with 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 = let possible_calls =
IList.filter IList.filter
(fun proc -> Procname.java_get_method proc = str_frame.method_str) (fun proc -> Procname.java_get_method proc = str_frame.method_str)
decl_procs in def_methods in
if IList.length possible_calls > 0 then if IList.length possible_calls > 0 then
(* using IList.hd here assumes that all of the possible calls are declared in the (* 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 *) * 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 = let get_field_name program static tenv cn fs context =
match JTransType.get_class_type_no_pointer program tenv cn with 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, _, _ = let fieldname, _, _ =
try try
IList.find IList.find
(fun (fieldname, _, _) -> retrieve_fieldname fieldname = JBasics.fs_name fs) (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 -> with Not_found ->
(* TODO: understand why fields cannot be found here *) (* TODO: understand why fields cannot be found here *)
JUtils.log "cannot find %s.%s@." (JBasics.cn_name cn) (JBasics.fs_name fs); 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 = let extract_cn_no_obj typ =
match typ with 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 let class_name = (Mangled.to_string classname) in
if class_name = JConfig.object_cl then None if class_name = JConfig.object_cl then None
else else
@ -239,7 +240,15 @@ let collect_interface_field cn inf l =
let dummy_type cn = let dummy_type cn =
let classname = Mangled.from_string (JBasics.cn_name cn) in 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 = 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 rec get_all_fields program tenv cn =
let extract_class_fields classname = let extract_class_fields classname =
match get_class_type_no_pointer program tenv classname with 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 | _ -> assert false in
let trans_fields classname = let trans_fields classname =
match JClasspath.lookup_node classname program with match JClasspath.lookup_node classname program with
@ -307,7 +316,7 @@ and create_sil_type program tenv cn =
| Some node -> | Some node ->
let create_super_list interface_names = let create_super_list interface_names =
IList.map typename_of_classname interface_names in 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 match node with
| Javalib.JInterface jinterface -> | Javalib.JInterface jinterface ->
let static_fields, _ = get_all_fields program tenv cn in let static_fields, _ = get_all_fields program tenv cn in
@ -326,15 +335,22 @@ and create_sil_type program tenv cn =
| Some super_cn -> | Some super_cn ->
let super_classname = let super_classname =
match get_class_type_no_pointer program tenv super_cn with 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) Typename.TN_csu (Csu.Class, classname)
| _ -> assert false in | _ -> assert false in
super_classname :: interface_list in super_classname :: interface_list in
(super_classname_list, nonstatic_fields, static_fields, item_annotation) in (super_classname_list, nonstatic_fields, static_fields, item_annotation) in
let classname = Mangled.from_string (JBasics.cn_name cn) in let classname = Mangled.from_string (JBasics.cn_name cn) in
let method_procnames = get_class_procnames cn node in let def_methods = get_class_procnames cn node in
Sil.Tstruct (nonstatic_fields, static_fields, Csu.Class, Sil.Tstruct {
Some classname, super_list, method_procnames, item_annotation) 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 = and get_class_type_no_pointer program tenv cn =

Loading…
Cancel
Save