make RequiredProps an `interprocedural`

Summary: Making checkers/ its own dune library.

Reviewed By: ezgicicek

Differential Revision: D21407072

fbshipit-source-id: 30be2816a
master
Jules Villard 5 years ago committed by Facebook GitHub Bot
parent 7e5dba718a
commit b6a7120b5f

@ -123,7 +123,9 @@ let all_checkers =
; callbacks= [(interprocedural Payloads.Fields.siof Siof.checker, Language.Clang)] } ; callbacks= [(interprocedural Payloads.Fields.siof Siof.checker, Language.Clang)] }
; { name= "litho-required-props" ; { name= "litho-required-props"
; active= Config.is_checker_enabled LithoRequiredProps ; active= Config.is_checker_enabled LithoRequiredProps
; callbacks= [(Procedure RequiredProps.checker, Language.Java)] } ; callbacks=
[(interprocedural Payloads.Fields.litho_required_props RequiredProps.checker, Language.Java)]
}
; (* toy resource analysis to use in the infer lab, see the lab/ directory *) ; (* toy resource analysis to use in the infer lab, see the lab/ directory *)
{ name= "resource leak" { name= "resource leak"
; active= Config.is_checker_enabled ResourceLeak ; active= Config.is_checker_enabled ResourceLeak

@ -9,12 +9,6 @@ open! IStd
module F = Format module F = Format
module Domain = LithoDomain module Domain = LithoDomain
module Payload = SummaryPayload.Make (struct
type t = Domain.summary
let field = Payloads.Fields.litho_required_props
end)
(* VarProp is only for props that have a varArg parameter like (* VarProp is only for props that have a varArg parameter like
@Prop(varArg = "var_prop") whereas Prop is for everything except. *) @Prop(varArg = "var_prop") whereas Prop is for everything except. *)
type required_prop = Prop of string | VarProp of {prop: string; var_prop: string} type required_prop = Prop of string | VarProp of {prop: string; var_prop: string}
@ -65,7 +59,7 @@ let get_required_props typename tenv =
[] []
let report_missing_required_prop summary prop parent_typename ~create_loc call_chain = let report_missing_required_prop proc_attrs err_log prop parent_typename ~create_loc call_chain =
let message = let message =
let prop_string = let prop_string =
match prop with match prop with
@ -88,7 +82,8 @@ let report_missing_required_prop summary prop parent_typename ~create_loc call_c
in in
Errlog.make_trace_element 0 location call_msg [] ) Errlog.make_trace_element 0 location call_msg [] )
in in
SummaryReporting.log_error summary ~loc:create_loc ~ltr IssueType.missing_required_prop message Reporting.log_error proc_attrs err_log ~loc:create_loc ~ltr IssueType.missing_required_prop
message
let has_prop prop_set prop = let has_prop prop_set prop =
@ -184,26 +179,27 @@ let should_report proc_desc tenv =
(not (is_litho_function pname)) && not (is_component_build_method pname tenv) (not (is_litho_function pname)) && not (is_component_build_method pname tenv)
let report astate tenv summary = let report {InterproceduralAnalysis.proc_desc; tenv; err_log} astate =
let check_on_string_set parent_typename create_loc call_chain prop_set = let check_on_string_set parent_typename create_loc call_chain prop_set =
let required_props = get_required_props parent_typename tenv in let required_props = get_required_props parent_typename tenv in
let attrs = Procdesc.get_attributes proc_desc in
List.iter required_props ~f:(fun required_prop -> List.iter required_props ~f:(fun required_prop ->
if not (has_prop prop_set required_prop) then if not (has_prop prop_set required_prop) then
report_missing_required_prop summary required_prop parent_typename ~create_loc call_chain report_missing_required_prop attrs err_log required_prop parent_typename ~create_loc
) call_chain )
in in
Domain.check_required_props ~check_on_string_set astate Domain.check_required_props ~check_on_string_set astate
type get_proc_summary_and_formals = Procname.t -> (Domain.summary * (Pvar.t * Typ.t) list) option type analysis_data =
{ analysis_data: LithoDomain.summary InterproceduralAnalysis.t
; get_proc_summary_and_formals: Procname.t -> (Domain.summary * (Pvar.t * Typ.t) list) option }
module TransferFunctions = struct module TransferFunctions = struct
module CFG = ProcCfg.Normal module CFG = ProcCfg.Normal
module Domain = LithoDomain module Domain = LithoDomain
type extras = {get_proc_summary_and_formals: get_proc_summary_and_formals} type nonrec analysis_data = analysis_data
type analysis_data = extras ProcData.t
let apply_callee_summary summary_opt callsite ~caller_pname ~callee_pname ret_id_typ formals let apply_callee_summary summary_opt callsite ~caller_pname ~callee_pname ret_id_typ formals
actuals astate = actuals astate =
@ -212,9 +208,9 @@ module TransferFunctions = struct
~caller:astate ~callee:callee_summary ) ~caller:astate ~callee:callee_summary )
let exec_instr astate ProcData.{summary; tenv; extras= {get_proc_summary_and_formals}} _ let exec_instr astate {analysis_data= {proc_desc; tenv}; get_proc_summary_and_formals} _
(instr : HilInstr.t) : Domain.t = (instr : HilInstr.t) : Domain.t =
let caller_pname = Summary.get_proc_name summary in let caller_pname = Procdesc.get_proc_name proc_desc in
match instr with match instr with
| Call | Call
( return_base ( return_base
@ -285,31 +281,25 @@ end
module Analyzer = LowerHil.MakeAbstractInterpreter (TransferFunctions) module Analyzer = LowerHil.MakeAbstractInterpreter (TransferFunctions)
let init_extras summary = let init_analysis_data ({InterproceduralAnalysis.analyze_dependency} as analysis_data) =
let get_proc_summary_and_formals callee_pname = let get_proc_summary_and_formals callee_pname =
Payload.read_full ~caller_summary:summary ~callee_pname analyze_dependency callee_pname
|> Option.map ~f:(fun (callee_pdesc, callee_summary) -> |> Option.map ~f:(fun (callee_pdesc, callee_summary) ->
(callee_summary, Procdesc.get_pvar_formals callee_pdesc) ) (callee_summary, Procdesc.get_pvar_formals callee_pdesc) )
in in
{TransferFunctions.get_proc_summary_and_formals} {analysis_data; get_proc_summary_and_formals}
let checker {Callbacks.summary; exe_env} = let checker ({InterproceduralAnalysis.proc_desc; tenv} as analysis_data) =
let proc_desc = Summary.get_proc_desc summary in let proc_name = Procdesc.get_proc_name proc_desc in
let proc_name = Summary.get_proc_name summary in
let tenv = Exe_env.get_tenv exe_env (Summary.get_proc_name summary) in
let proc_data = {ProcData.summary; tenv; extras= init_extras summary} in
let ret_path = let ret_path =
let ret_var = Procdesc.get_ret_var proc_desc in let ret_var = Procdesc.get_ret_var proc_desc in
let ret_typ = Procdesc.get_ret_type proc_desc in let ret_typ = Procdesc.get_ret_type proc_desc in
Domain.LocalAccessPath.make_from_pvar ret_var ret_typ proc_name Domain.LocalAccessPath.make_from_pvar ret_var ret_typ proc_name
in in
let initial = Domain.init tenv proc_name (Procdesc.get_pvar_formals proc_desc) ret_path in let initial = Domain.init tenv proc_name (Procdesc.get_pvar_formals proc_desc) ret_path in
match Analyzer.compute_post proc_data ~initial proc_desc with Analyzer.compute_post (init_analysis_data analysis_data) ~initial proc_desc
| Some post -> |> Option.map ~f:(fun post ->
let is_void_func = Procdesc.get_ret_type proc_desc |> Typ.is_void in let is_void_func = Procdesc.get_ret_type proc_desc |> Typ.is_void in
let post = Domain.get_summary ~is_void_func post in let post = Domain.get_summary ~is_void_func post in
let post = if should_report proc_desc tenv then report post tenv summary else post in if should_report proc_desc tenv then report analysis_data post else post )
Payload.update_summary post summary
| None ->
summary

@ -0,0 +1,10 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
val checker : LithoDomain.summary InterproceduralAnalysis.t -> LithoDomain.summary option
Loading…
Cancel
Save