diff --git a/infer/src/absint/exe_env.ml b/infer/src/absint/exe_env.ml index bac17a399e..eea1e3e53e 100644 --- a/infer/src/absint/exe_env.ml +++ b/infer/src/absint/exe_env.ml @@ -7,63 +7,34 @@ *) open! IStd -module F = Format - -(** Execution environments: basically a cache of where procedures are and what is their CFG and type - environment *) - module L = Logging -(** per-file data: type environment and integer widths *) -type file_data = {tenv: Tenv.t option Lazy.t; integer_type_widths: IntegerWidths.t option Lazy.t} - -(** create a new file_data *) -let[@alert "-tenv"] new_file_data source = - (* exceptionally allow [Tenv.load] as it goes through a cache *) - { tenv= lazy (Tenv.load source) - ; integer_type_widths= - lazy (Option.first_some (IntegerWidths.load source) (Some IntegerWidths.java)) } - - -type t = {proc_map: SourceFile.t Procname.Hash.t; file_map: file_data SourceFile.Hash.t} - -let file_data_of_source {file_map} source = - match SourceFile.Hash.find_opt file_map source with - | Some file_data -> - file_data - | None -> - let file_data = new_file_data source in - SourceFile.Hash.add file_map source file_data ; - file_data +type t = + {tenvs_map: Tenv.t option SourceFile.Hash.t; int_widths_map: IntegerWidths.t SourceFile.Hash.t} +let mk () = {tenvs_map= SourceFile.Hash.create 1; int_widths_map= SourceFile.Hash.create 1} -let get_file_data exe_env pname = - match Procname.Hash.find_opt exe_env.proc_map pname with - | Some source -> - Some (file_data_of_source exe_env source) +let[@alert "-tenv"] get_source_tenv exe_env source = + match SourceFile.Hash.find_opt exe_env.tenvs_map source with + | Some tenv_opt -> + tenv_opt | None -> ( - match Attributes.load pname with - | None -> - L.debug Analysis Medium "can't find attributes for %a@." Procname.pp pname ; - None - | Some proc_attributes -> - let source_file = proc_attributes.ProcAttributes.translation_unit in - let file_data = file_data_of_source exe_env source_file in - Procname.Hash.add exe_env.proc_map pname source_file ; - Some file_data ) - - -let file_data_to_tenv file_data = Lazy.force file_data.tenv + match Tenv.load source with + | None when Config.log_missing_deps -> + raise MissingDependencyException.MissingDependencyException + | v -> + SourceFile.Hash.add exe_env.tenvs_map source v ; + v ) -let file_data_to_integer_type_widths file_data = Lazy.force file_data.integer_type_widths -let java_global_tenv = - lazy - ( match Tenv.load_global () with - | None -> - L.(die InternalError) "Could not load the global tenv" - | Some tenv -> - tenv ) +let get_proc_source pname = + match Attributes.load pname with + | Some proc_attributes -> + proc_attributes.ProcAttributes.translation_unit + | None when Config.log_missing_deps -> + raise MissingDependencyException.MissingDependencyException + | None -> + L.die InternalError "exe_env: could not find procedure attributes for %a@\n" Procname.pp pname let load_java_global_tenv _exe_env = @@ -72,55 +43,32 @@ let load_java_global_tenv _exe_env = If somebody wants to fetch java global environment, they'd better have exe_env instance provided. If they don't they are probably doing something wrong. *) - Lazy.force java_global_tenv + match Tenv.load_global () with + | None -> + L.die InternalError "Could not load the global tenv" + | Some tenv -> + tenv -let get_column_value ~value_on_java ~file_data_to_value ~column_name exe_env proc_name = - let pp_loc_opt f = function - | Some loc -> - F.fprintf f " in file '%a' at %a" SourceFile.pp loc.Location.file Location.pp loc - | None -> - () - in - match proc_name with +let get_proc_tenv exe_env pname = + match pname with | Procname.Java _ -> - Lazy.force value_on_java - | _ -> ( - match get_file_data exe_env proc_name with - | Some file_data -> ( - match file_data_to_value file_data with - | Some v -> - v - | None when Config.log_missing_deps -> - raise MissingDependencyException.MissingDependencyException - | None -> - let loc_opt = AnalysisState.get_loc () in - L.die InternalError "get_column_value: %s not found for %a%a" column_name Procname.pp - proc_name pp_loc_opt loc_opt ) - | None when Config.log_missing_deps -> - raise MissingDependencyException.MissingDependencyException + load_java_global_tenv exe_env + | _ -> + get_proc_source pname |> get_source_tenv exe_env + |> Option.value_or_thunk ~default:(fun () -> + L.die InternalError "exe_env: could not find tenv for %a@\n" Procname.pp pname ) + + +let get_integer_type_widths exe_env pname = + let source = get_proc_source pname in + match SourceFile.Hash.find_opt exe_env.int_widths_map source with + | Some widths -> + widths + | None -> ( + match IntegerWidths.load source with + | Some widths -> + SourceFile.Hash.add exe_env.int_widths_map source widths ; + widths | None -> - let loc_opt = AnalysisState.get_loc () in - L.die InternalError "get_column_value: file_data not found for %a%a" Procname.pp proc_name - pp_loc_opt loc_opt ) - - -(** return the type environment associated to the procedure *) -let get_proc_tenv = - get_column_value ~value_on_java:java_global_tenv ~file_data_to_value:file_data_to_tenv - ~column_name:"tenv" - - -let get_source_tenv exe_env source = - let file_data = file_data_of_source exe_env source in - Lazy.force file_data.tenv - - -(** return the integer type widths associated to the procedure *) -let get_integer_type_widths = - get_column_value - ~value_on_java:(lazy IntegerWidths.java) - ~file_data_to_value:file_data_to_integer_type_widths ~column_name:"integer type widths" - - -let mk () = {proc_map= Procname.Hash.create 17; file_map= SourceFile.Hash.create 1} + IntegerWidths.java )