[infer] Use typ instead of root_typ if possible

Summary:
This diff makes the checkers, except biabduction, to use `typ` instead
of `root_typ` of `Load`/`Store` statemetns.

Reviewed By: dulmarod

Differential Revision: D17203105

fbshipit-source-id: 8be9b5158
master
Sungkeun Cho 5 years ago committed by Facebook Github Bot
parent 3916d1b3bc
commit 962e56cb1b

@ -71,18 +71,17 @@ let inline_synthetic_method ((ret_id, _) as ret) etl pdesc loc_call : Sil.instr
in
let do_instr instr =
match (instr, etl) with
| ( Sil.Load {e= Exp.Lfield (Exp.Var _, fn, ft); root_typ= bt; typ}
, [(* getter for fields *) (e1, _)] ) ->
| Sil.Load {e= Exp.Lfield (Exp.Var _, fn, ft); root_typ; typ}, [(* getter for fields *) (e1, _)]
->
let instr' =
Sil.Load {id= ret_id; e= Exp.Lfield (e1, fn, ft); root_typ= bt; typ; loc= loc_call}
Sil.Load {id= ret_id; e= Exp.Lfield (e1, fn, ft); root_typ; typ; loc= loc_call}
in
found instr instr'
| Sil.Load {e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ= bt; typ}, []
when Pvar.is_global pvar ->
| Sil.Load {e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ; typ}, [] when Pvar.is_global pvar
->
(* getter for static fields *)
let instr' =
Sil.Load
{id= ret_id; e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ= bt; typ; loc= loc_call}
Sil.Load {id= ret_id; e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ; typ; loc= loc_call}
in
found instr instr'
| ( Sil.Store {e1= Exp.Lfield (_, fn, ft); root_typ; typ}

@ -58,9 +58,9 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr : Sil.instr) =
Instr (Assign (HilExp.AccessExpression.base (lhs_id, rhs_typ), rhs_hil_exp, loc))
in
match instr with
| Load {id= lhs_id; e= rhs_exp; root_typ= rhs_typ; loc} ->
| Load {id= lhs_id; e= rhs_exp; typ= rhs_typ; loc} ->
analyze_id_assignment ~add_deref:true (Var.of_id lhs_id) rhs_exp rhs_typ loc
| Store {e1= Lvar lhs_pvar; root_typ= lhs_typ; e2= rhs_exp; loc}
| Store {e1= Lvar lhs_pvar; typ= lhs_typ; e2= rhs_exp; loc}
when Pvar.is_ssa_frontend_tmp lhs_pvar ->
(* do not need to add deref here as it is added implicitly in of_pvar by forgetting the & *)
analyze_id_assignment (Var.of_pvar lhs_pvar) rhs_exp lhs_typ loc
@ -72,7 +72,7 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr : Sil.instr) =
, _ )
when Typ.Procname.equal callee_pname BuiltinDecl.__cast ->
analyze_id_assignment (Var.of_id ret_id) target_exp cast_typ loc
| Store {e1= lhs_exp; root_typ= typ; e2= rhs_exp; loc} ->
| Store {e1= lhs_exp; typ; e2= rhs_exp; loc} ->
let lhs_access_expr =
match HilExp.access_expr_of_exp ~include_array_indexes ~f_resolve_id lhs_exp typ with
| Some access_expr ->

@ -83,8 +83,8 @@ let with_formals_types_proc callee_pdesc resolved_pdesc substitutions =
in
Some
(Sil.Load {id; e= convert_exp origin_exp; root_typ= updated_typ; typ= updated_typ; loc})
| Sil.Load {id; e= origin_exp; root_typ= origin_typ; typ; loc} ->
Some (Sil.Load {id; e= convert_exp origin_exp; root_typ= origin_typ; typ; loc})
| Sil.Load {id; e= origin_exp; root_typ; typ; loc} ->
Some (Sil.Load {id; e= convert_exp origin_exp; root_typ; typ; loc})
| Sil.Store {e1= assignee_exp; root_typ= origin_typ; e2= origin_exp; loc} ->
let set_instr =
Sil.Store
@ -230,8 +230,8 @@ let with_block_args_instrs resolved_pdesc substitutions =
let id_map = Ident.Map.add id (Pvar.get_name block_param) id_map in
(* we don't need the load the block param instruction anymore *)
(instrs, id_map)
| Sil.Load {id; e= origin_exp; root_typ= origin_typ; typ; loc} ->
(Sil.Load {id; e= convert_exp origin_exp; root_typ= origin_typ; typ; loc} :: instrs, id_map)
| Sil.Load {id; e= origin_exp; root_typ; typ; loc} ->
(Sil.Load {id; e= convert_exp origin_exp; root_typ; typ; loc} :: instrs, id_map)
| Sil.Store {e1= assignee_exp; root_typ= origin_typ; e2= Exp.Var id; loc}
when Ident.Map.mem id id_map ->
let block_param = Ident.Map.find id id_map in

@ -179,7 +179,7 @@ let get_vararg_type_names tenv (call_node : Procdesc.Node.t) (ivar : Pvar.t) : s
let nvar_type_name nvar =
instrs
|> Instrs.find_map ~f:(function
| Sil.Load {id= nv; e; root_typ= t} when Ident.equal nv nvar ->
| Sil.Load {id= nv; e; typ= t} when Ident.equal nv nvar ->
Some (e, t)
| _ ->
None )

@ -198,7 +198,7 @@ module TransferFunctions = struct
L.d_printfln_escaped "/!\\ Failed to get initializer name of global constant %a"
(Pvar.pp Pp.text) pvar ;
Dom.Mem.add_unknown id ~location mem )
| Load {id; e= exp; root_typ= typ} ->
| Load {id; e= exp; typ} ->
let represents_multiple_values = is_array_access_exp exp in
BoUtils.Exec.load_locs ~represents_multiple_values id typ (Sem.eval_locs exp mem) mem
| Store {e1= exp1; e2= Const (Const.Cstr s); loc= location} ->
@ -210,7 +210,7 @@ module TransferFunctions = struct
in
let do_alloc = not (Sem.is_stack_exp exp1 mem) in
BoUtils.Exec.decl_string model_env ~do_alloc locs s mem
| Store {e1= exp1; root_typ= typ; e2= exp2; loc= location} ->
| Store {e1= exp1; typ; e2= exp2; loc= location} ->
let locs = Sem.eval_locs exp1 mem in
let v =
Sem.eval integer_type_widths exp2 mem |> Dom.Val.add_assign_trace_elem location locs

@ -43,7 +43,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Sil.Load {id; e= exp} ->
Ident.Hash.add proc_data.extras id exp ;
astate
| Sil.Store {e1= Exp.Lfield (Exp.Var lhs_id, name, typ); root_typ= exp_typ; e2= rhs} -> (
| Sil.Store {e1= Exp.Lfield (Exp.Var lhs_id, name, typ); typ= exp_typ; e2= rhs} -> (
match exp_typ.Typ.desc with
(* block field of a ObjC class *)
| Typ.Tptr ({desc= Tfun _}, _)

@ -139,7 +139,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let exec_instr astate {ProcData.summary} _ (instr : Sil.instr) =
match instr with
| Store {e1= Lvar global; root_typ= Typ.{desc= Tptr _}; e2= Lvar _; loc}
| Store {e1= Lvar global; typ= Typ.{desc= Tptr _}; e2= Lvar _; loc}
when (Option.equal Typ.Procname.equal)
(Pvar.get_initializer_pname global)
(Some (Summary.get_proc_name summary)) ->

@ -36,7 +36,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let exec_instr astate _ _ = function
| Sil.Store {root_typ= {desc= Tptr _}; e2= rhs_exp} ->
| Sil.Store {typ= {desc= Tptr _}; e2= rhs_exp} ->
add_address_taken_pvars rhs_exp astate
| Sil.Call (_, _, actuals, _, _) ->
let add_actual_by_ref astate_acc = function

@ -26,8 +26,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let exec_instr astate _ _ = function
| Sil.Load {id= lhs_id} when Ident.is_none lhs_id ->
astate
| Sil.Load {id= lhs_id; e= Exp.Lvar rhs_pvar; root_typ= Typ.{desc= Tptr ({desc= Tfun _}, _)}}
->
| Sil.Load {id= lhs_id; e= Exp.Lvar rhs_pvar; typ= Typ.{desc= Tptr ({desc= Tfun _}, _)}} ->
let fun_ptr =
try Domain.find (Pvar.to_string rhs_pvar) astate
with Caml.Not_found -> ProcnameSet.empty

@ -263,7 +263,7 @@ let checker {Callbacks.exe_env; summary} : Summary.t =
Reporting.log_error summary ~loc ~ltr IssueType.dead_store message
in
let report_dead_store live_vars captured_by_ref_vars = function
| Sil.Store {e1= Lvar pvar; root_typ= typ; e2= rhs_exp; loc}
| Sil.Store {e1= Lvar pvar; typ; e2= rhs_exp; loc}
when should_report pvar typ live_vars captured_by_ref_vars && not (is_sentinel_exp rhs_exp)
->
log_report pvar typ loc

@ -133,10 +133,10 @@ let get_ptr_vars_in_defn_path node loop_head var =
Procdesc.Node.get_instrs node
|> Instrs.fold ~init:InvalidatedVars.empty ~f:(fun acc instr ->
match instr with
| Sil.Load {id; e= exp_rhs; root_typ= typ}
| Sil.Load {id; e= exp_rhs; typ}
when Var.equal var (Var.of_id id) && is_non_primitive typ ->
invalidate_exp exp_rhs acc
| Sil.Store {e1= Exp.Lvar pvar; root_typ= typ; e2= exp_rhs}
| Sil.Store {e1= Exp.Lvar pvar; typ; e2= exp_rhs}
when Var.equal var (Var.of_pvar pvar) && is_non_primitive typ ->
invalidate_exp exp_rhs acc
| _ ->

@ -421,14 +421,14 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p
astate )
| Sil.Metadata (Abstract _ | Nullify _ | Skip | VariableLifetimeBegins _) ->
typestate
| Sil.Load {id; e; root_typ= typ; loc} ->
| Sil.Load {id; e; typ; loc} ->
typecheck_expr_for_errors typestate e loc ;
let e', typestate' = convert_complex_exp_to_pvar node false e typestate loc in
TypeState.add_id id (typecheck_expr_simple typestate' e' typ TypeOrigin.Undef loc) typestate'
| Sil.Store {e1= Exp.Lvar pvar; e2= Exp.Exn _} when is_return pvar ->
(* skip assignment to return variable where it is an artifact of a throw instruction *)
typestate
| Sil.Store {e1; root_typ= typ; e2; loc} ->
| Sil.Store {e1; typ; e2; loc} ->
typecheck_expr_for_errors typestate e1 loc ;
let e1', typestate1 = convert_complex_exp_to_pvar node true e1 typestate loc in
let check_field_assign () =

Loading…
Cancel
Save