From 30ae60461e3e75699ab71ef50f3a9aef613f24b1 Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Wed, 15 Mar 2017 22:56:43 -0700 Subject: [PATCH] [infer][backend] Fail when no callback is registered to run the analysis on-demand Summary: Fail early when there is no registered callbacks to run the analysis of a procedure on-demand Reviewed By: sblackshear Differential Revision: D4573726 fbshipit-source-id: a8ee74b --- infer/src/IR/AttributesTable.re | 11 +++++++---- infer/src/backend/ondemand.ml | 19 ++++++++++++------- infer/src/unit/TaintTests.ml | 11 +++++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/infer/src/IR/AttributesTable.re b/infer/src/IR/AttributesTable.re index 714dfd46f..69fdc79b2 100644 --- a/infer/src/IR/AttributesTable.re +++ b/infer/src/IR/AttributesTable.re @@ -38,7 +38,7 @@ let attributes_filename proc_kind::proc_kind pname_file => { /** path to the .attr file for the given procedure in the current results directory */ -let res_dir_attr_filename proc_kind::proc_kind pname => { +let res_dir_attr_filename create_dir::create_dir proc_kind::proc_kind pname => { let pname_file = Typ.Procname.to_filename pname; let attr_fname = attributes_filename proc_kind::proc_kind pname_file; let bucket_dir = { @@ -53,7 +53,9 @@ let res_dir_attr_filename proc_kind::proc_kind pname => { let filename = DB.Results_dir.path_to_filename DB.Results_dir.Abs_root [Config.attributes_dir_name, bucket_dir, attr_fname]; - DB.filename_create_dir filename; + if create_dir { + DB.filename_create_dir filename + }; filename }; @@ -61,7 +63,7 @@ let res_dir_attr_filename proc_kind::proc_kind pname => { otherwise try to load the declared filename. */ let load_attr defined_only::defined_only proc_name => { let attributes_file proc_kind::proc_kind proc_name => Multilinks.resolve ( - res_dir_attr_filename proc_kind::proc_kind proc_name + res_dir_attr_filename create_dir::false proc_kind::proc_kind proc_name ); let attr = Serialization.read_from_file serializer (attributes_file proc_kind::ProcDefined proc_name); @@ -102,7 +104,8 @@ let less_relevant_proc_kinds proc_kind => If defined, delete the declared file if it exists. */ let write_and_delete proc_name (proc_attributes: ProcAttributes.t) => { let proc_kind = create_proc_kind proc_attributes; - let attributes_file proc_kind => res_dir_attr_filename proc_kind::proc_kind proc_name; + let attributes_file proc_kind => + res_dir_attr_filename create_dir::true proc_kind::proc_kind proc_name; Serialization.write_to_file serializer (attributes_file proc_kind) data::proc_attributes; let upgrade_relevance less_relevant_proc_kind => { let fname_declared = DB.filename_to_string (attributes_file less_relevant_proc_kind); diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index ed96e2e0f..915488b7e 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -188,16 +188,17 @@ let analyze_proc_desc ~propagate_exceptions curr_pdesc callee_pdesc : Specs.summ let callee_pname = Procdesc.get_proc_name callee_pdesc in let proc_attributes = Procdesc.get_attributes callee_pdesc in match !callbacks_ref with + | None -> + failwithf + "No callbacks registered to analyze proc desc %a when analyzing %a@." + Typ.Procname.pp callee_pname + Typ.Procname.pp (Procdesc.get_proc_name curr_pdesc) | Some callbacks -> if should_be_analyzed callee_pname proc_attributes then - let summary = - run_proc_analysis - ~propagate_exceptions callbacks.analyze_ondemand curr_pdesc callee_pdesc in - Some summary + Some (run_proc_analysis + ~propagate_exceptions callbacks.analyze_ondemand curr_pdesc callee_pdesc) else Specs.get_summary callee_pname - | None -> None - (** analyze_proc_name curr_pdesc proc_name @@ -205,6 +206,11 @@ let analyze_proc_desc ~propagate_exceptions curr_pdesc callee_pdesc : Specs.summ triggered during the analysis of curr_pname. *) let analyze_proc_name ~propagate_exceptions curr_pdesc callee_pname : Specs.summary option = match !callbacks_ref with + | None -> + failwithf + "No callbacks registered to analyze proc name %a when analyzing %a@." + Typ.Procname.pp callee_pname + Typ.Procname.pp (Procdesc.get_proc_name curr_pdesc) | Some callbacks -> if procedure_should_be_analyzed callee_pname then begin @@ -215,7 +221,6 @@ let analyze_proc_name ~propagate_exceptions curr_pdesc callee_pname : Specs.summ end else Specs.get_summary callee_pname - | None -> None (** Find a proc desc for the procedure, perhaps loading it from disk. *) diff --git a/infer/src/unit/TaintTests.ml b/infer/src/unit/TaintTests.ml index 3baff2462..501f8a904 100644 --- a/infer/src/unit/TaintTests.ml +++ b/infer/src/unit/TaintTests.ml @@ -108,6 +108,17 @@ let tests = let read_field_to_id lhs_id_str root_str fld_str = make_load_fld ~rhs_typ:Typ.Tvoid lhs_id_str fld_str (Exp.Var (ident_of_str root_str)) in let assert_empty = invariant "{ }" in + (* hack: register an empty analyze_ondemand to prevent a crash because the callback is unset *) + let analyze_ondemand _ proc_desc = + let proc_name = Procdesc.get_proc_name proc_desc in + Specs.reset_summary proc_name None None in + let get_proc_desc _ = None in + let callbacks = + { + Ondemand.analyze_ondemand; + get_proc_desc; + } in + Ondemand.set_callbacks callbacks; let test_list = [ "source recorded", [