diff --git a/infer/man/man1/infer-explore.txt b/infer/man/man1/infer-explore.txt index 5d5ec578c..b93bb2f2f 100644 --- a/infer/man/man1/infer-explore.txt +++ b/infer/man/man1/infer-explore.txt @@ -83,10 +83,6 @@ OPTIONS Activates: Print source files discovered by infer (Conversely: --no-source-files) - --source-files-cfgs - Activates: Print the Cfgs of each source file in the output of - --source-files (Conversely: --no-source-files-cfgs) - --source-files-filter filter With --source-files, only print source files matching the specified filter. The filter is a pattern that should match the diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index 8148f66ab..49c70f938 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -785,11 +785,6 @@ OPTIONS Activates: Print source files discovered by infer (Conversely: --no-source-files) See also infer-explore(1). - --source-files-cfgs - Activates: Print the Cfgs of each source file in the output of - --source-files (Conversely: --no-source-files-cfgs) - See also infer-explore(1). - --source-files-filter filter With --source-files, only print source files matching the specified filter. The filter is a pattern that should match the diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index c6ca78ab6..e704de676 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -785,11 +785,6 @@ OPTIONS Activates: Print source files discovered by infer (Conversely: --no-source-files) See also infer-explore(1). - --source-files-cfgs - Activates: Print the Cfgs of each source file in the output of - --source-files (Conversely: --no-source-files-cfgs) - See also infer-explore(1). - --source-files-filter filter With --source-files, only print source files matching the specified filter. The filter is a pattern that should match the diff --git a/infer/src/IR/Cfg.ml b/infer/src/IR/Cfg.ml index aabd85e8c..3bd8d2a72 100644 --- a/infer/src/IR/Cfg.ml +++ b/infer/src/IR/Cfg.ml @@ -50,10 +50,6 @@ let iter_all_nodes ~sorted cfg ~f = |> List.iter ~f:(fun node -> f pdesc node) ) -module SQLite = SqliteUtils.MarshalledData (struct - type nonrec t = t -end) - let store source_file cfg = let save_proc _ proc_desc = let attributes = Procdesc.get_attributes proc_desc in @@ -148,8 +144,3 @@ let pp_proc_signatures fmt cfg = F.fprintf fmt "@[METHOD SIGNATURES@;" ; iter_over_sorted_procs ~f:(Procdesc.pp_signature fmt) cfg ; F.fprintf fmt "@]" - - -let merge ~src ~dst = - Typ.Procname.Hash.iter (fun pname cfg -> Typ.Procname.Hash.replace dst pname cfg) src ; - dst diff --git a/infer/src/IR/Cfg.mli b/infer/src/IR/Cfg.mli index 9e88e665c..43d2ea58c 100644 --- a/infer/src/IR/Cfg.mli +++ b/infer/src/IR/Cfg.mli @@ -34,10 +34,4 @@ val iter_all_nodes : sorted:bool -> t -> f:(Procdesc.t -> Procdesc.Node.t -> uni val inline_java_synthetic_methods : t -> unit (** Inline the java synthetic methods in the cfg (in-place) *) -val merge : src:t -> dst:t -> t -(** Best-effort merge of [src] into [dst]. If a procedure is both in [dst] and [src], the one in - [src] will get overwritten. *) - val pp_proc_signatures : Format.formatter -> t -> unit - -module SQLite : SqliteUtils.Data with type t = t diff --git a/infer/src/IR/SourceFiles.ml b/infer/src/IR/SourceFiles.ml index d12b99467..1f6570ab2 100644 --- a/infer/src/IR/SourceFiles.ml +++ b/infer/src/IR/SourceFiles.ml @@ -12,12 +12,12 @@ let store_statement = ResultsDatabase.register_statement {| INSERT OR REPLACE INTO source_files - VALUES (:source, :cfgs, :tenv, :proc_names, :freshly_captured) |} + VALUES (:source, :tenv, :proc_names, :freshly_captured) |} let select_existing_statement = ResultsDatabase.register_statement - "SELECT cfgs, type_environment FROM source_files WHERE source_file = :source AND \ + "SELECT type_environment, procedure_names FROM source_files WHERE source_file = :source AND \ freshly_captured = 1" @@ -27,27 +27,38 @@ let get_existing_data source_file = |> Sqlite3.bind stmt 1 (* :source *) |> SqliteUtils.check_result_code db ~log:"get_existing_data bind source file" ; - SqliteUtils.result_option ~finalize:false db ~log:"looking for pre-existing cfgs" stmt - ~read_row:(fun stmt -> - let cfgs = Sqlite3.column stmt 0 |> Cfg.SQLite.deserialize - and tenv = Sqlite3.column stmt 1 |> Tenv.SQLite.deserialize in - (cfgs, tenv) ) ) + SqliteUtils.result_option ~finalize:false db ~log:"looking for pre-existing source file data" + stmt ~read_row:(fun stmt -> + let tenv = Sqlite3.column stmt 0 |> Tenv.SQLite.deserialize + and proc_names = Sqlite3.column stmt 1 |> Typ.Procname.SQLiteList.deserialize in + (tenv, proc_names) ) ) let add source_file cfg tenv = Cfg.inline_java_synthetic_methods cfg ; - let cfg, tenv = + let tenv, proc_names = (* The same source file may get captured several times in a single capture event, for instance because it is compiled with different options, or from different symbolic links. This may generate different procedures in each phase, so make an attempt to merge them into the same - CFG. *) + tenv. *) + let new_proc_names = Cfg.get_all_defined_proc_names cfg in match get_existing_data source_file with - | Some (old_cfg, old_tenv) -> + | Some (old_tenv, old_proc_names) -> L.debug Capture Quiet "Merging capture data for already-captured '%a'@\n" SourceFile.pp source_file ; - (Cfg.merge ~dst:old_cfg ~src:cfg, Tenv.merge ~dst:old_tenv ~src:tenv) + (* merge the proc names defined in the source file using a hashtbl so that order is + preserved but merging is still linear time *) + let existing_proc_names = Caml.Hashtbl.create (List.length old_proc_names) in + List.iter old_proc_names ~f:(fun proc_name -> + Caml.Hashtbl.add existing_proc_names proc_name () ) ; + let proc_names = + List.fold new_proc_names ~init:old_proc_names ~f:(fun proc_names proc_name -> + if not (Caml.Hashtbl.mem existing_proc_names proc_name) then proc_name :: proc_names + else proc_names ) + in + (Tenv.merge ~dst:old_tenv ~src:tenv, proc_names) | None -> - (cfg, tenv) + (tenv, new_proc_names) in (* NOTE: it's important to write attribute files to disk before writing cfgs to disk. OndemandCapture module relies on it - it uses existance of the cfg as a barrier to make @@ -59,17 +70,14 @@ let add source_file cfg tenv = |> Sqlite3.bind store_stmt 1 (* :source *) |> SqliteUtils.check_result_code db ~log:"store bind source file" ; - Cfg.SQLite.serialize cfg |> Sqlite3.bind store_stmt 2 - (* :cfg *) - |> SqliteUtils.check_result_code db ~log:"store bind cfg" ; - Tenv.SQLite.serialize tenv |> Sqlite3.bind store_stmt 3 + Tenv.SQLite.serialize tenv |> Sqlite3.bind store_stmt 2 (* :tenv *) |> SqliteUtils.check_result_code db ~log:"store bind type environment" ; - Cfg.get_all_defined_proc_names cfg - |> Typ.Procname.SQLiteList.serialize |> Sqlite3.bind store_stmt 4 + Typ.Procname.SQLiteList.serialize proc_names + |> Sqlite3.bind store_stmt 3 (* :proc_names *) |> SqliteUtils.check_result_code db ~log:"store bind proc names" ; - Sqlite3.bind store_stmt 5 (Sqlite3.Data.INT Int64.one) + Sqlite3.bind store_stmt 4 (Sqlite3.Data.INT Int64.one) (* :freshly_captured *) |> SqliteUtils.check_result_code db ~log:"store freshness" ; SqliteUtils.result_unit ~finalize:false ~log:"Cfg.store" db store_stmt ) @@ -160,7 +168,7 @@ let select_all_source_files_statement = ResultsDatabase.register_statement "SELECT * FROM source_files" -let pp_all ~filter ~cfgs ~type_environment ~procedure_names ~freshly_captured fmt () = +let pp_all ~filter ~type_environment ~procedure_names ~freshly_captured fmt () = let pp_procnames fmt procs = F.fprintf fmt "@[" ; List.iter ~f:(F.fprintf fmt "%a@," Typ.Procname.pp) procs ; @@ -171,17 +179,15 @@ let pp_all ~filter ~cfgs ~type_environment ~procedure_names ~freshly_captured fm F.fprintf fmt " @[%s@,%a@]@;" title pp (Sqlite3.column stmt column |> deserialize) in let pp_row stmt fmt source_file = - F.fprintf fmt "%a@,%a%a%a%a" SourceFile.pp source_file - (pp_if stmt "cfgs" cfgs Cfg.SQLite.deserialize Cfg.pp_proc_signatures) - 1 + F.fprintf fmt "%a@,%a%a%a" SourceFile.pp source_file (pp_if stmt "type_environment" type_environment Tenv.SQLite.deserialize Tenv.pp_per_file) - 2 + 1 (pp_if stmt "procedure_names" procedure_names Typ.Procname.SQLiteList.deserialize pp_procnames) - 3 + 2 (pp_if stmt "freshly_captured" freshly_captured deserialize_freshly_captured Format.pp_print_bool) - 4 + 3 in ResultsDatabase.with_registered_statement select_all_source_files_statement ~f:(fun db stmt -> let pp fmt column = diff --git a/infer/src/IR/SourceFiles.mli b/infer/src/IR/SourceFiles.mli index 9f4d2ae20..a5cde1294 100644 --- a/infer/src/IR/SourceFiles.mli +++ b/infer/src/IR/SourceFiles.mli @@ -30,7 +30,6 @@ val mark_all_stale : unit -> unit val pp_all : filter:Filtering.source_files_filter - -> cfgs:bool -> type_environment:bool -> procedure_names:bool -> freshly_captured:bool diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 64e3d1489..3828cbe54 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1933,12 +1933,6 @@ and source_files_filter = regular expressions." -and source_files_cfgs = - CLOpt.mk_bool ~long:"source-files-cfgs" - ~in_help:InferCommand.[(Explore, manual_generic)] - "Print the Cfgs of each source file in the output of $(b,--source-files)" - - and source_files_type_environment = CLOpt.mk_bool ~long:"source-files-type-environment" ~in_help:InferCommand.[(Explore, manual_generic)] @@ -2849,8 +2843,6 @@ and source_files = !source_files and source_files_filter = !source_files_filter -and source_files_cfgs = !source_files_cfgs - and source_files_type_environment = !source_files_type_environment and source_files_procedure_names = !source_files_procedure_names diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index d15437afb..b50fdf64e 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -591,8 +591,6 @@ val source_files : bool val source_files_filter : string option -val source_files_cfgs : bool - val source_files_type_environment : bool val source_files_procedure_names : bool diff --git a/infer/src/base/MergeResults.ml b/infer/src/base/MergeResults.ml index 65fe25435..3ebcff223 100644 --- a/infer/src/base/MergeResults.ml +++ b/infer/src/base/MergeResults.ml @@ -35,7 +35,7 @@ let merge_source_files_table ~db_file = Sqlite3.exec db {| INSERT OR REPLACE INTO source_files - SELECT source_file, cfgs, type_environment, procedure_names, 1 + SELECT source_file, type_environment, procedure_names, 1 FROM attached.source_files |} |> SqliteUtils.check_result_code db diff --git a/infer/src/base/ResultsDatabase.ml b/infer/src/base/ResultsDatabase.ml index b14ced37e..5ac1d9d58 100644 --- a/infer/src/base/ResultsDatabase.ml +++ b/infer/src/base/ResultsDatabase.ml @@ -26,7 +26,6 @@ let procedures_schema = let source_files_schema = {|CREATE TABLE IF NOT EXISTS source_files ( source_file TEXT PRIMARY KEY - , cfgs BLOB NOT NULL , type_environment BLOB NOT NULL , procedure_names BLOB NOT NULL , freshly_captured INT NOT NULL )|} diff --git a/infer/src/infer.ml b/infer/src/infer.ml index 81cf355c0..3caffb15c 100644 --- a/infer/src/infer.ml +++ b/infer/src/infer.ml @@ -154,7 +154,7 @@ let () = L.result "%a" (SourceFiles.pp_all ~filter:(Lazy.force Filtering.source_files_filter) - ~cfgs:Config.source_files_cfgs ~type_environment:Config.source_files_type_environment + ~type_environment:Config.source_files_type_environment ~procedure_names:Config.source_files_procedure_names ~freshly_captured:Config.source_files_freshly_captured) ()