diff --git a/infer/src/backend/registerCheckers.ml b/infer/src/backend/registerCheckers.ml index 3119efaba..7e062805c 100644 --- a/infer/src/backend/registerCheckers.ml +++ b/infer/src/backend/registerCheckers.ml @@ -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 diff --git a/infer/src/checkers/RequiredProps.ml b/infer/src/checkers/RequiredProps.ml index a8a9a7b42..7cf1c3cc0 100644 --- a/infer/src/checkers/RequiredProps.ml +++ b/infer/src/checkers/RequiredProps.ml @@ -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 ) diff --git a/infer/src/checkers/RequiredProps.mli b/infer/src/checkers/RequiredProps.mli new file mode 100644 index 000000000..4e6c68566 --- /dev/null +++ b/infer/src/checkers/RequiredProps.mli @@ -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