[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 in
let do_instr instr = let do_instr instr =
match (instr, etl) with match (instr, etl) with
| ( Sil.Load {e= Exp.Lfield (Exp.Var _, fn, ft); root_typ= bt; typ} | Sil.Load {e= Exp.Lfield (Exp.Var _, fn, ft); root_typ; typ}, [(* getter for fields *) (e1, _)]
, [(* getter for fields *) (e1, _)] ) -> ->
let instr' = 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 in
found instr instr' found instr instr'
| Sil.Load {e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ= bt; typ}, [] | Sil.Load {e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ; typ}, [] when Pvar.is_global pvar
when Pvar.is_global pvar -> ->
(* getter for static fields *) (* getter for static fields *)
let instr' = let instr' =
Sil.Load Sil.Load {id= ret_id; e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ; typ; loc= loc_call}
{id= ret_id; e= Exp.Lfield (Exp.Lvar pvar, fn, ft); root_typ= bt; typ; loc= loc_call}
in in
found instr instr' found instr instr'
| ( Sil.Store {e1= Exp.Lfield (_, fn, ft); root_typ; typ} | ( 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)) Instr (Assign (HilExp.AccessExpression.base (lhs_id, rhs_typ), rhs_hil_exp, loc))
in in
match instr with 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 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 -> 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 & *) (* 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 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 -> when Typ.Procname.equal callee_pname BuiltinDecl.__cast ->
analyze_id_assignment (Var.of_id ret_id) target_exp cast_typ loc 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 = let lhs_access_expr =
match HilExp.access_expr_of_exp ~include_array_indexes ~f_resolve_id lhs_exp typ with match HilExp.access_expr_of_exp ~include_array_indexes ~f_resolve_id lhs_exp typ with
| Some access_expr -> | Some access_expr ->

@ -83,8 +83,8 @@ let with_formals_types_proc callee_pdesc resolved_pdesc substitutions =
in in
Some Some
(Sil.Load {id; e= convert_exp origin_exp; root_typ= updated_typ; typ= updated_typ; loc}) (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} -> | Sil.Load {id; e= origin_exp; root_typ; typ; loc} ->
Some (Sil.Load {id; e= convert_exp origin_exp; root_typ= origin_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} -> | Sil.Store {e1= assignee_exp; root_typ= origin_typ; e2= origin_exp; loc} ->
let set_instr = let set_instr =
Sil.Store 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 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 *) (* we don't need the load the block param instruction anymore *)
(instrs, id_map) (instrs, id_map)
| Sil.Load {id; e= origin_exp; root_typ= origin_typ; typ; loc} -> | Sil.Load {id; e= origin_exp; root_typ; typ; loc} ->
(Sil.Load {id; e= convert_exp origin_exp; root_typ= origin_typ; typ; loc} :: instrs, id_map) (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} | Sil.Store {e1= assignee_exp; root_typ= origin_typ; e2= Exp.Var id; loc}
when Ident.Map.mem id id_map -> when Ident.Map.mem id id_map ->
let block_param = Ident.Map.find id id_map in 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 = let nvar_type_name nvar =
instrs instrs
|> Instrs.find_map ~f:(function |> 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) Some (e, t)
| _ -> | _ ->
None ) None )

@ -198,7 +198,7 @@ module TransferFunctions = struct
L.d_printfln_escaped "/!\\ Failed to get initializer name of global constant %a" L.d_printfln_escaped "/!\\ Failed to get initializer name of global constant %a"
(Pvar.pp Pp.text) pvar ; (Pvar.pp Pp.text) pvar ;
Dom.Mem.add_unknown id ~location mem ) 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 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 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} -> | Store {e1= exp1; e2= Const (Const.Cstr s); loc= location} ->
@ -210,7 +210,7 @@ module TransferFunctions = struct
in in
let do_alloc = not (Sem.is_stack_exp exp1 mem) in let do_alloc = not (Sem.is_stack_exp exp1 mem) in
BoUtils.Exec.decl_string model_env ~do_alloc locs s mem 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 locs = Sem.eval_locs exp1 mem in
let v = let v =
Sem.eval integer_type_widths exp2 mem |> Dom.Val.add_assign_trace_elem location locs 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} -> | Sil.Load {id; e= exp} ->
Ident.Hash.add proc_data.extras id exp ; Ident.Hash.add proc_data.extras id exp ;
astate 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 match exp_typ.Typ.desc with
(* block field of a ObjC class *) (* block field of a ObjC class *)
| Typ.Tptr ({desc= Tfun _}, _) | Typ.Tptr ({desc= Tfun _}, _)

@ -139,7 +139,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let exec_instr astate {ProcData.summary} _ (instr : Sil.instr) = let exec_instr astate {ProcData.summary} _ (instr : Sil.instr) =
match instr with 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) when (Option.equal Typ.Procname.equal)
(Pvar.get_initializer_pname global) (Pvar.get_initializer_pname global)
(Some (Summary.get_proc_name summary)) -> (Some (Summary.get_proc_name summary)) ->

@ -36,7 +36,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let exec_instr astate _ _ = function 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 add_address_taken_pvars rhs_exp astate
| Sil.Call (_, _, actuals, _, _) -> | Sil.Call (_, _, actuals, _, _) ->
let add_actual_by_ref astate_acc = function let add_actual_by_ref astate_acc = function

@ -26,8 +26,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let exec_instr astate _ _ = function let exec_instr astate _ _ = function
| Sil.Load {id= lhs_id} when Ident.is_none lhs_id -> | Sil.Load {id= lhs_id} when Ident.is_none lhs_id ->
astate 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 = let fun_ptr =
try Domain.find (Pvar.to_string rhs_pvar) astate try Domain.find (Pvar.to_string rhs_pvar) astate
with Caml.Not_found -> ProcnameSet.empty 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 Reporting.log_error summary ~loc ~ltr IssueType.dead_store message
in in
let report_dead_store live_vars captured_by_ref_vars = function 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) when should_report pvar typ live_vars captured_by_ref_vars && not (is_sentinel_exp rhs_exp)
-> ->
log_report pvar typ loc 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 Procdesc.Node.get_instrs node
|> Instrs.fold ~init:InvalidatedVars.empty ~f:(fun acc instr -> |> Instrs.fold ~init:InvalidatedVars.empty ~f:(fun acc instr ->
match instr with 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 -> when Var.equal var (Var.of_id id) && is_non_primitive typ ->
invalidate_exp exp_rhs acc 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 -> when Var.equal var (Var.of_pvar pvar) && is_non_primitive typ ->
invalidate_exp exp_rhs acc invalidate_exp exp_rhs acc
| _ -> | _ ->

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

Loading…
Cancel
Save