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)] }
; { name= "litho-required-props"
; 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 *)
{ name= "resource leak"
; active= Config.is_checker_enabled ResourceLeak

@ -9,12 +9,6 @@ open! IStd
module F = Format
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
@Prop(varArg = "var_prop") whereas Prop is for everything except. *)
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 prop_string =
match prop with
@ -88,7 +82,8 @@ let report_missing_required_prop summary prop parent_typename ~create_loc call_c
in
Errlog.make_trace_element 0 location call_msg [] )
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 =
@ -184,26 +179,27 @@ let should_report proc_desc 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 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 ->
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
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 CFG = ProcCfg.Normal
module Domain = LithoDomain
type extras = {get_proc_summary_and_formals: get_proc_summary_and_formals}
type analysis_data = extras ProcData.t
type nonrec analysis_data = analysis_data
let apply_callee_summary summary_opt callsite ~caller_pname ~callee_pname ret_id_typ formals
actuals astate =
@ -212,9 +208,9 @@ module TransferFunctions = struct
~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 =
let caller_pname = Summary.get_proc_name summary in
let caller_pname = Procdesc.get_proc_name proc_desc in
match instr with
| Call
( return_base
@ -285,31 +281,25 @@ end
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 =
Payload.read_full ~caller_summary:summary ~callee_pname
analyze_dependency callee_pname
|> Option.map ~f:(fun (callee_pdesc, callee_summary) ->
(callee_summary, Procdesc.get_pvar_formals callee_pdesc) )
in
{TransferFunctions.get_proc_summary_and_formals}
{analysis_data; get_proc_summary_and_formals}
let checker {Callbacks.summary; exe_env} =
let proc_desc = Summary.get_proc_desc summary 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 checker ({InterproceduralAnalysis.proc_desc; tenv} as analysis_data) =
let proc_name = Procdesc.get_proc_name proc_desc in
let ret_path =
let ret_var = Procdesc.get_ret_var proc_desc in
let ret_typ = Procdesc.get_ret_type proc_desc in
Domain.LocalAccessPath.make_from_pvar ret_var ret_typ proc_name
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
| Some post ->
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 = if should_report proc_desc tenv then report post tenv summary else post in
Payload.update_summary post summary
| None ->
summary
Analyzer.compute_post (init_analysis_data analysis_data) ~initial proc_desc
|> Option.map ~f:(fun post ->
let is_void_func = Procdesc.get_ret_type proc_desc |> Typ.is_void in
let post = Domain.get_summary ~is_void_func post in
if should_report proc_desc tenv then report analysis_data post else post )

@ -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