diff --git a/infer/src/IR/Attributes.ml b/infer/src/IR/Attributes.ml index c17dbd14d..14a6a9eef 100644 --- a/infer/src/IR/Attributes.ml +++ b/infer/src/IR/Attributes.ml @@ -61,7 +61,7 @@ FROM ( FROM procedures WHERE proc_name = :pname ) WHERE attr_kind < :akind - OR (attr_kind = :akind AND source_file < :sfile) )|} + OR (attr_kind = :akind AND source_file <= :sfile) )|} let replace pname pname_blob akind loc_file attr_blob proc_desc = diff --git a/infer/src/IR/ProcAttributes.ml b/infer/src/IR/ProcAttributes.ml index 31d7efa6c..480be23ca 100644 --- a/infer/src/IR/ProcAttributes.ml +++ b/infer/src/IR/ProcAttributes.ml @@ -63,6 +63,9 @@ type t = ; proc_name: Typ.Procname.t (** name of the procedure *) ; ret_type: Typ.t (** return type *) ; has_added_return_param: bool (** whether or not a return param was added *) } +[@@deriving compare] + +let equal = [%compare.equal: t] let default translation_unit proc_name = { access= PredSymb.Default @@ -165,7 +168,7 @@ let pp f F.fprintf f "; clang_method_kind= %a@," (Pp.to_string ~f:ClangMethodKind.to_string) clang_method_kind ; - if not (Location.equal default.loc loc) then F.fprintf f "; loc= %a@," Location.pp loc ; + if not (Location.equal default.loc loc) then F.fprintf f "; loc= %a@," Location.pp_file_pos loc ; if not ([%compare.equal: var_data list] default.locals locals) then F.fprintf f "; locals= [@[%a@]]@," (Pp.semicolon_seq ~print_env:Pp.text_break pp_var_data) diff --git a/infer/src/IR/ProcAttributes.mli b/infer/src/IR/ProcAttributes.mli index ea9365133..25c4a8676 100644 --- a/infer/src/IR/ProcAttributes.mli +++ b/infer/src/IR/ProcAttributes.mli @@ -47,6 +47,9 @@ type t = ; ret_type: Typ.t (** return type *) ; has_added_return_param: bool (** whether or not a return param was added *) } +val equal : t -> t -> bool [@@warning "-32"] +(** can be useful for debugging *) + val default : SourceFile.t -> Typ.Procname.t -> t (** Create a proc_attributes with default values. *) diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index 62c80d813..bc392e9aa 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -755,3 +755,15 @@ let is_connected proc_desc = module SQLite = SqliteUtils.MarshalledNullableData (struct type nonrec t = t end) + +let load_statement = + ResultsDatabase.register_statement "SELECT cfg FROM procedures WHERE proc_name = :k" + + +let load pname = + ResultsDatabase.with_registered_statement load_statement ~f:(fun db stmt -> + Typ.Procname.SQLite.serialize pname + |> Sqlite3.bind stmt 1 + |> SqliteUtils.check_result_code db ~log:"load bind proc name" ; + SqliteUtils.result_single_column_option ~finalize:false ~log:"Procdesc.load" db stmt + |> Option.bind ~f:SQLite.deserialize ) diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index 1b9ec82b1..24052d641 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -291,3 +291,5 @@ val is_connected : t -> (unit, [`Join | `Other]) Result.t (** per-procedure CFGs are stored in the SQLite "procedures" table as NULL if the procedure has no CFG *) module SQLite : SqliteUtils.Data with type t = t option + +val load : Typ.Procname.t -> t option diff --git a/infer/src/backend/callbacks.ml b/infer/src/backend/callbacks.ml index 8d2b41d8e..8c3e72d10 100644 --- a/infer/src/backend/callbacks.ml +++ b/infer/src/backend/callbacks.ml @@ -44,11 +44,10 @@ let register_cluster_callback ~name language (callback : cluster_callback_t) = (** Collect what we need to know about a procedure for the analysis. *) let get_procedure_definition exe_env proc_name = - Option.map - ~f:(fun proc_desc -> - let tenv = Exe_env.get_tenv exe_env proc_name in - (tenv, proc_desc) ) - (Exe_env.get_proc_desc exe_env proc_name) + Procdesc.load proc_name + |> Option.map ~f:(fun proc_desc -> + let tenv = Exe_env.get_tenv exe_env proc_name in + (tenv, proc_desc) ) (** Invoke all registered procedure callbacks on the given procedure. *) @@ -57,11 +56,14 @@ let iterate_procedure_callbacks exe_env summary proc_desc = let procedure_language = Typ.Procname.get_language proc_name in Language.curr_language := procedure_language ; let get_procs_in_file proc_name = - match Exe_env.get_cfg exe_env proc_name with - | Some cfg -> - Cfg.get_all_defined_proc_names cfg - | None -> - [] + let source_file = + match Attributes.load proc_name with + | Some {ProcAttributes.translation_unit} -> + Some translation_unit + | None -> + None + in + Option.value_map source_file ~default:[] ~f:SourceFiles.proc_names_of_source in let tenv = Exe_env.get_tenv exe_env proc_name in let is_specialized = Procdesc.is_specialized proc_desc in diff --git a/infer/src/backend/exe_env.ml b/infer/src/backend/exe_env.ml index f4d411b2d..c7020d21d 100644 --- a/infer/src/backend/exe_env.ml +++ b/infer/src/backend/exe_env.ml @@ -14,15 +14,13 @@ open! IStd module L = Logging (** per-file data: type environment and cfg *) -type file_data = {source: SourceFile.t; mutable tenv: Tenv.t option; mutable cfg: Cfg.t option} +type file_data = {source: SourceFile.t; mutable tenv: Tenv.t option} (** create a new file_data *) let new_file_data source = (* Do not fill in tenv and cfg as they can be quite large. This makes calls to fork() cheaper until we start filling out these fields. *) - { source - ; tenv= None (* Sil.load_tenv_from_file tenv_file *) - ; cfg= None (* Cfg.load_cfg_from_file cfg_file *) } + {source; tenv= None (* Sil.load_tenv_from_file tenv_file *)} let create_file_data table source = @@ -65,11 +63,6 @@ let file_data_to_tenv file_data = file_data.tenv -let file_data_to_cfg file_data = - if is_none file_data.cfg then file_data.cfg <- Cfg.load file_data.source ; - file_data.cfg - - let java_global_tenv = lazy ( match Tenv.load_global () with @@ -102,22 +95,4 @@ let get_tenv exe_env proc_name = SourceFile.pp loc.Location.file Location.pp loc ) -(** return the cfg associated to the procedure *) -let get_cfg exe_env pname = - match get_file_data exe_env pname with - | None -> - None - | Some file_data -> - file_data_to_cfg file_data - - -(** return the proc desc associated to the procedure *) -let get_proc_desc exe_env pname = - match get_cfg exe_env pname with - | Some cfg -> - Typ.Procname.Hash.find_opt cfg pname - | None -> - None - - let mk () = {proc_map= Typ.Procname.Hash.create 17; file_map= SourceFile.Hash.create 1} diff --git a/infer/src/backend/exe_env.mli b/infer/src/backend/exe_env.mli index 819dc8655..cd02a495d 100644 --- a/infer/src/backend/exe_env.mli +++ b/infer/src/backend/exe_env.mli @@ -8,7 +8,7 @@ open! IStd -(** Execution environments: basically a cache of where procedures are and what is their CFG and type +(** Execution environments: basically a cache of where procedures are and what is their type environment *) type file_data @@ -22,9 +22,3 @@ val mk : unit -> t val get_tenv : t -> Typ.Procname.t -> Tenv.t (** return the type environment associated with the procedure *) - -val get_cfg : t -> Typ.Procname.t -> Cfg.t option -(** return the cfg associated with the procedure *) - -val get_proc_desc : t -> Typ.Procname.t -> Procdesc.t option -(** return the proc desc associated with the procedure *) diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index f34256af9..f6c98b82b 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -236,8 +236,7 @@ let analyze_proc_desc ~caller_pdesc callee_pdesc = (** Find a proc desc for the procedure, perhaps loading it from disk. *) let get_proc_desc callee_pname = - let callbacks = Option.value_exn !callbacks_ref in - match Exe_env.get_proc_desc callbacks.exe_env callee_pname with + match Procdesc.load callee_pname with | Some _ as pdesc_opt -> pdesc_opt | None -> diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index bbd70eb2c..0a5caae49 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -61,7 +61,7 @@ let do_source_file (translation_unit_context : CFrontend_config.translation_unit Config.debug_mode || Config.testing_mode || Config.frontend_tests || Option.is_some Config.icfg_dotty_outfile then Dotty.print_icfg_dotty source_file cfg ; - L.(debug Capture Verbose) "%a" Cfg.pp_proc_signatures cfg ; + L.(debug Capture Verbose) "Stored on disk:@[%a@]@." Cfg.pp_proc_signatures cfg ; let procedures_translated_summary = EventLogger.ProceduresTranslatedSummary { procedures_translated_total= !CFrontend_config.procedures_attempted