[specs] put specs files operations in their own module

Summary:
Summary.ml defines both a bunch of types and how to use them and a
mechanism to save and store summaries on disk while maintaining a
complex in-memory cache of what's on disk. Make the distinction clear.

Reviewed By: ngorogiannis

Differential Revision: D16358869

fbshipit-source-id: 9d4c6cb77
master
Jules Villard 5 years ago committed by Facebook Github Bot
parent 124ab9fed7
commit 73179f7182

@ -13,7 +13,7 @@ open! IStd
let new_session node = let new_session node =
let pname = Procdesc.Node.get_proc_name node in let pname = Procdesc.Node.get_proc_name node in
let node_id = (Procdesc.Node.get_id node :> int) in let node_id = (Procdesc.Node.get_id node :> int) in
match Summary.get pname with match Summary.OnDisk.get pname with
| None -> | None ->
0 0
| Some summary -> | Some summary ->

@ -13,7 +13,7 @@ module L = Logging
let clear_caches () = let clear_caches () =
Ondemand.clear_cache () ; Ondemand.clear_cache () ;
Summary.clear_cache () ; Summary.OnDisk.clear_cache () ;
Typ.Procname.SQLite.clear_cache () Typ.Procname.SQLite.clear_cache ()
@ -91,7 +91,7 @@ let main ~changed_files =
register_active_checkers () ; register_active_checkers () ;
if Config.reanalyze then ( if Config.reanalyze then (
L.progress "Invalidating procedures to be reanalyzed@." ; L.progress "Invalidating procedures to be reanalyzed@." ;
Summary.reset_all ~filter:(Lazy.force Filtering.procedures_filter) () ; Summary.OnDisk.reset_all ~filter:(Lazy.force Filtering.procedures_filter) () ;
L.progress "Done@." ) L.progress "Done@." )
else DB.Results_dir.clean_specs_dir () ; else DB.Results_dir.clean_specs_dir () ;
let n_all_source_files = ref 0 in let n_all_source_files = ref 0 in

@ -50,7 +50,7 @@ let spec_files_from_cmdline () =
let summary_iterator spec_files = let summary_iterator spec_files =
let sorted_spec_files = List.sort ~compare:String.compare (spec_files ()) in let sorted_spec_files = List.sort ~compare:String.compare (spec_files ()) in
let do_spec f fname = let do_spec f fname =
match Summary.load_from_file (DB.filename_from_string fname) with match Summary.OnDisk.load_from_file (DB.filename_from_string fname) with
| None -> | None ->
L.(die UserError) "Error: cannot open file %s@." fname L.(die UserError) "Error: cannot open file %s@." fname
| Some summary -> | Some summary ->
@ -65,5 +65,7 @@ let iter_from_config ~f = summary_iterator spec_files_from_cmdline f
let iter ~f = summary_iterator load_specfiles f let iter ~f = summary_iterator load_specfiles f
let delete pname = let delete pname =
let filename = Summary.specs_filename_of_procname pname |> DB.filename_to_string in let filename = Summary.OnDisk.specs_filename_of_procname pname |> DB.filename_to_string in
Unix.unlink filename ; Ondemand.remove_from_cache pname ; Summary.remove_from_cache pname Unix.unlink filename ;
Ondemand.remove_from_cache pname ;
Summary.OnDisk.remove_from_cache pname

@ -8,7 +8,6 @@
open! IStd open! IStd
module F = Format module F = Format
open PolyVariantEqual
module Stats = struct module Stats = struct
type t = type t =
@ -96,14 +95,6 @@ let get_err_log summary = summary.err_log
let get_loc summary = (get_attributes summary).ProcAttributes.loc let get_loc summary = (get_attributes summary).ProcAttributes.loc
type cache = t Typ.Procname.Hash.t
let cache : cache = Typ.Procname.Hash.create 128
let clear_cache () = Typ.Procname.Hash.clear cache
let remove_from_cache pname = Typ.Procname.Hash.remove cache pname
let pp_errlog fmt err_log = let pp_errlog fmt err_log =
F.fprintf fmt "ERRORS: @[<h>%a@]@\n%!" Errlog.pp_errors err_log ; F.fprintf fmt "ERRORS: @[<h>%a@]@\n%!" Errlog.pp_errors err_log ;
F.fprintf fmt "WARNINGS: @[<h>%a@]" Errlog.pp_warnings err_log F.fprintf fmt "WARNINGS: @[<h>%a@]" Errlog.pp_warnings err_log
@ -139,142 +130,155 @@ let pp_html source fmt summary =
F.fprintf fmt "</LISTING>@\n" F.fprintf fmt "</LISTING>@\n"
(** Add the summary to the table for the given function *) module OnDisk = struct
let add (proc_name : Typ.Procname.t) (summary : t) : unit = open PolyVariantEqual
Typ.Procname.Hash.replace cache proc_name summary
type cache = t Typ.Procname.Hash.t
let specs_filename pname = let cache : cache = Typ.Procname.Hash.create 128
let pname_file = Typ.Procname.to_filename pname in
pname_file ^ Config.specs_files_suffix
let clear_cache () = Typ.Procname.Hash.clear cache
(** Return the path to the .specs file for the given procedure in the current results directory *) let remove_from_cache pname = Typ.Procname.Hash.remove cache pname
let specs_filename_of_procname pname =
DB.Results_dir.path_to_filename DB.Results_dir.Abs_root
[Config.specs_dir_name; specs_filename pname]
(** Add the summary to the table for the given function *)
let add (proc_name : Typ.Procname.t) (summary : t) : unit =
Typ.Procname.Hash.replace cache proc_name summary
(** paths to the .specs file for the given procedure in the current spec libraries *)
let specs_library_filename specs_dir pname =
DB.filename_from_string (Filename.concat specs_dir (specs_filename pname))
let specs_filename pname =
let pname_file = Typ.Procname.to_filename pname in
pname_file ^ Config.specs_files_suffix
(** paths to the .specs file for the given procedure in the models folder *)
let specs_models_filename pname =
DB.filename_from_string (Filename.concat Config.models_dir (specs_filename pname))
(** Return the path to the .specs file for the given procedure in the current results directory *)
let specs_filename_of_procname pname =
DB.Results_dir.path_to_filename DB.Results_dir.Abs_root
[Config.specs_dir_name; specs_filename pname]
let has_model pname = Sys.file_exists (DB.filename_to_string (specs_models_filename pname)) = `Yes
let summary_serializer : t Serialization.serializer = (** paths to the .specs file for the given procedure in the current spec libraries *)
Serialization.create_serializer Serialization.Key.summary let specs_library_filename specs_dir pname =
DB.filename_from_string (Filename.concat specs_dir (specs_filename pname))
(** Load procedure summary from the given file *) (** paths to the .specs file for the given procedure in the models folder *)
let load_from_file specs_file = Serialization.read_from_file summary_serializer specs_file let specs_models_filename pname =
DB.filename_from_string (Filename.concat Config.models_dir (specs_filename pname))
(** Load procedure summary for the given procedure name and update spec table *)
let load_summary_to_spec_table =
let rec or_load_summary_libs specs_dirs proc_name summ_opt =
match (summ_opt, specs_dirs) with
| Some _, _ | _, [] ->
summ_opt
| None, specs_dir :: specs_dirs ->
load_from_file (specs_library_filename specs_dir proc_name)
|> or_load_summary_libs specs_dirs proc_name
in
let load_summary_ziplibs zip_specs_filename =
let zip_specs_path = Filename.concat Config.specs_dir_name zip_specs_filename in
ZipLib.load summary_serializer zip_specs_path
in
let or_from f_load f_filenames proc_name summ_opt =
match summ_opt with Some _ -> summ_opt | None -> f_load (f_filenames proc_name)
in
fun proc_name ->
let summ_opt =
load_from_file (specs_filename_of_procname proc_name)
|> or_from load_from_file specs_models_filename proc_name
|> or_from load_summary_ziplibs specs_filename proc_name
|> or_load_summary_libs Config.specs_library proc_name
in
Option.iter ~f:(add proc_name) summ_opt ;
summ_opt
let has_model pname =
Sys.file_exists (DB.filename_to_string (specs_models_filename pname)) = `Yes
let get proc_name =
try Some (Typ.Procname.Hash.find cache proc_name)
with Caml.Not_found -> load_summary_to_spec_table proc_name
let summary_serializer : t Serialization.serializer =
Serialization.create_serializer Serialization.Key.summary
(** Check if the procedure is from a library:
(** Load procedure summary from the given file *)
let load_from_file specs_file = Serialization.read_from_file summary_serializer specs_file
(** Load procedure summary for the given procedure name and update spec table *)
let load_summary_to_spec_table =
let rec or_load_summary_libs specs_dirs proc_name summ_opt =
match (summ_opt, specs_dirs) with
| Some _, _ | _, [] ->
summ_opt
| None, specs_dir :: specs_dirs ->
load_from_file (specs_library_filename specs_dir proc_name)
|> or_load_summary_libs specs_dirs proc_name
in
let load_summary_ziplibs zip_specs_filename =
let zip_specs_path = Filename.concat Config.specs_dir_name zip_specs_filename in
ZipLib.load summary_serializer zip_specs_path
in
let or_from f_load f_filenames proc_name summ_opt =
match summ_opt with Some _ -> summ_opt | None -> f_load (f_filenames proc_name)
in
fun proc_name ->
let summ_opt =
load_from_file (specs_filename_of_procname proc_name)
|> or_from load_from_file specs_models_filename proc_name
|> or_from load_summary_ziplibs specs_filename proc_name
|> or_load_summary_libs Config.specs_library proc_name
in
Option.iter ~f:(add proc_name) summ_opt ;
summ_opt
let get proc_name =
match Typ.Procname.Hash.find cache proc_name with
| summary ->
Some summary
| exception Caml.Not_found ->
load_summary_to_spec_table proc_name
(** Check if the procedure is from a library:
It's not defined, and there is no spec file for it. *) It's not defined, and there is no spec file for it. *)
let proc_is_library proc_attributes = let proc_is_library proc_attributes =
if not proc_attributes.ProcAttributes.is_defined then if not proc_attributes.ProcAttributes.is_defined then
match get proc_attributes.ProcAttributes.proc_name with None -> true | Some _ -> false match get proc_attributes.ProcAttributes.proc_name with None -> true | Some _ -> false
else false else false
(** Try to find the attributes for a defined proc. (** Try to find the attributes for a defined proc.
First look at specs (to get attributes computed by analysis) First look at specs (to get attributes computed by analysis)
then look at the attributes table. then look at the attributes table.
If no attributes can be found, return None. If no attributes can be found, return None.
*) *)
let proc_resolve_attributes proc_name = let proc_resolve_attributes proc_name =
match get proc_name with match get proc_name with
| Some summary -> | Some summary ->
Some (get_attributes summary) Some (get_attributes summary)
| None -> | None ->
Attributes.load proc_name Attributes.load proc_name
(** Save summary for the procedure into the spec database *) (** Save summary for the procedure into the spec database *)
let store (summ : t) = let store (summ : t) =
let final_summary = {summ with status= Status.Analyzed} in let final_summary = {summ with status= Status.Analyzed} in
let proc_name = get_proc_name final_summary in let proc_name = get_proc_name final_summary in
(* Make sure the summary in memory is identical to the saved one *) (* Make sure the summary in memory is identical to the saved one *)
add proc_name final_summary ; add proc_name final_summary ;
Serialization.write_to_file summary_serializer Serialization.write_to_file summary_serializer
(specs_filename_of_procname proc_name) (specs_filename_of_procname proc_name)
~data:final_summary ~data:final_summary
let init_summary proc_desc = let reset proc_desc =
let summary = let summary =
{ sessions= ref 0 { sessions= ref 0
; payloads= Payloads.empty ; payloads= Payloads.empty
; stats= Stats.empty ; stats= Stats.empty
; status= Status.Pending ; status= Status.Pending
; proc_desc ; proc_desc
; err_log= Errlog.empty () ; err_log= Errlog.empty ()
; callee_pnames= Typ.Procname.Set.empty } ; callee_pnames= Typ.Procname.Set.empty }
in in
Typ.Procname.Hash.replace cache (Procdesc.get_proc_name proc_desc) summary ; Typ.Procname.Hash.replace cache (Procdesc.get_proc_name proc_desc) summary ;
summary summary
let dummy =
let dummy_attributes =
ProcAttributes.default (SourceFile.invalid __FILE__) Typ.Procname.empty_block
in
let dummy_proc_desc = Procdesc.from_proc_attributes dummy_attributes in
init_summary dummy_proc_desc
(** Reset a summary rebuilding the dependents and preserving the proc attributes if present. *)
let reset proc_desc = init_summary proc_desc
let reset_all ~filter () =
let reset proc_name =
let filename = specs_filename_of_procname proc_name in
Serialization.read_from_file summary_serializer filename
|> Option.iter ~f:(fun summary ->
let blank_summary = reset summary.proc_desc in
Serialization.write_to_file summary_serializer filename ~data:blank_summary )
in
Procedures.get_all ~filter () |> List.iter ~f:reset
let dummy =
let dummy_attributes =
ProcAttributes.default (SourceFile.invalid __FILE__) Typ.Procname.empty_block
in
let dummy_proc_desc = Procdesc.from_proc_attributes dummy_attributes in
reset dummy_proc_desc
let reset_all ~filter () =
let reset proc_name =
let filename = specs_filename_of_procname proc_name in
Serialization.read_from_file summary_serializer filename
|> Option.iter ~f:(fun summary ->
let blank_summary = reset summary.proc_desc in
Serialization.write_to_file summary_serializer filename ~data:blank_summary )
in
Procedures.get_all ~filter () |> List.iter ~f:reset
end
module SummaryValue = struct module SummaryValue = struct
type nonrec t = t option type nonrec t = t option

@ -51,22 +51,6 @@ type t =
val poly_fields : t PolyFields.t val poly_fields : t PolyFields.t
val dummy : t
(** dummy summary for testing *)
val has_model : Typ.Procname.t -> bool
(** Check if a summary for a given procedure exists in the models directory *)
val clear_cache : unit -> unit
(** Remove all the elements from the cache of summaries *)
val remove_from_cache : Typ.Procname.t -> unit
(** Remove an element from the cache of summaries. Contrast to reset which re-initializes a summary
keeping the same Procdesc and updates the cache accordingly. *)
val get : Typ.Procname.t -> t option
(** Return the summary option for the procedure name *)
val get_proc_name : t -> Typ.Procname.t val get_proc_name : t -> Typ.Procname.t
(** Get the procedure name *) (** Get the procedure name *)
@ -88,36 +72,54 @@ val get_signature : t -> string
val get_status : t -> Status.t val get_status : t -> Status.t
(** Return the status (active v.s. inactive) of a procedure summary *) (** Return the status (active v.s. inactive) of a procedure summary *)
val reset : Procdesc.t -> t
(** Reset a summary rebuilding the dependents and preserving the proc attributes if present. *)
val specs_filename_of_procname : Typ.Procname.t -> DB.filename
(** Return the path to the .specs file for the given procedure in the current results directory *)
val load_from_file : DB.filename -> t option
(** Load procedure summary from the given file *)
val pp_html : SourceFile.t -> Format.formatter -> t -> unit val pp_html : SourceFile.t -> Format.formatter -> t -> unit
(** Print the summary in html format *) (** Print the summary in html format *)
val pp_text : Format.formatter -> t -> unit val pp_text : Format.formatter -> t -> unit
(** Print the summary in text format *) (** Print the summary in text format *)
val proc_resolve_attributes : Typ.Procname.t -> ProcAttributes.t option module OnDisk : sig
(** Try to find the attributes for a defined proc. val has_model : Typ.Procname.t -> bool
(** Check if a summary for a given procedure exists in the models directory *)
val clear_cache : unit -> unit
(** Remove all the elements from the cache of summaries *)
val remove_from_cache : Typ.Procname.t -> unit
(** Remove an element from the cache of summaries. Contrast to reset which re-initializes a summary
keeping the same Procdesc and updates the cache accordingly. *)
val get : Typ.Procname.t -> t option
(** Return the summary option for the procedure name *)
val reset : Procdesc.t -> t
(** Reset a summary rebuilding the dependents and preserving the proc attributes if present. *)
val specs_filename_of_procname : Typ.Procname.t -> DB.filename
(** Return the path to the .specs file for the given procedure in the current results directory *)
val load_from_file : DB.filename -> t option
(** Load procedure summary from the given file *)
val proc_resolve_attributes : Typ.Procname.t -> ProcAttributes.t option
(** Try to find the attributes for a defined proc.
First look at specs (to get attributes computed by analysis) First look at specs (to get attributes computed by analysis)
then look at the attributes table. then look at the attributes table.
If no attributes can be found, return None. If no attributes can be found, return None.
*) *)
val proc_is_library : ProcAttributes.t -> bool val proc_is_library : ProcAttributes.t -> bool
(** Check if the procedure is from a library: (** Check if the procedure is from a library:
It's not defined, and there is no spec file for it. *) It's not defined, and there is no spec file for it. *)
val store : t -> unit val store : t -> unit
(** Save summary for the procedure into the spec database *) (** Save summary for the procedure into the spec database *)
val reset_all : filter:Filtering.procedures_filter -> unit -> unit val reset_all : filter:Filtering.procedures_filter -> unit -> unit
val dummy : t
(** dummy summary for testing *)
end
module SummaryValue : Memcached.Value with type t = t option module SummaryValue : Memcached.Value with type t = t option

@ -42,7 +42,7 @@ let get_procedure_definition exe_env proc_name =
Procdesc.load proc_name Procdesc.load proc_name
|> Option.map ~f:(fun proc_desc -> |> Option.map ~f:(fun proc_desc ->
let tenv = Exe_env.get_tenv exe_env proc_name in let tenv = Exe_env.get_tenv exe_env proc_name in
(tenv, Summary.reset proc_desc) ) (tenv, Summary.OnDisk.reset proc_desc) )
(** Invoke all registered procedure callbacks on the given procedure. *) (** Invoke all registered procedure callbacks on the given procedure. *)

@ -41,7 +41,7 @@ let is_active, add_active, remove_active =
let already_analyzed proc_name = let already_analyzed proc_name =
match Summary.get proc_name with match Summary.OnDisk.get proc_name with
| Some summary -> | Some summary ->
Summary.(Status.is_analyzed (get_status summary)) Summary.(Status.is_analyzed (get_status summary))
| None -> | None ->
@ -57,7 +57,7 @@ let should_be_analyzed proc_attributes =
let get_proc_attr proc_name = let get_proc_attr proc_name =
IList.force_until_first_some IList.force_until_first_some
[lazy (Summary.proc_resolve_attributes proc_name); lazy (Topl.get_proc_attr proc_name)] [lazy (Summary.OnDisk.proc_resolve_attributes proc_name); lazy (Topl.get_proc_attr proc_name)]
let procedure_should_be_analyzed proc_name = let procedure_should_be_analyzed proc_name =
@ -158,12 +158,12 @@ let run_proc_analysis ~caller_pdesc callee_pdesc =
Typ.Procname.pp callee_pname ; Typ.Procname.pp callee_pname ;
let preprocess () = let preprocess () =
incr nesting ; incr nesting ;
let initial_callee_summary = Summary.reset callee_pdesc in let initial_callee_summary = Summary.OnDisk.reset callee_pdesc in
add_active callee_pname ; initial_callee_summary add_active callee_pname ; initial_callee_summary
in in
let postprocess summary = let postprocess summary =
decr nesting ; decr nesting ;
Summary.store summary ; Summary.OnDisk.store summary ;
remove_active callee_pname ; remove_active callee_pname ;
Printer.write_proc_html callee_pdesc ; Printer.write_proc_html callee_pdesc ;
log_elapsed_time () ; log_elapsed_time () ;
@ -180,7 +180,10 @@ let run_proc_analysis ~caller_pdesc callee_pdesc =
{summary.payloads with biabduction} {summary.payloads with biabduction}
in in
let new_summary = {summary with stats; payloads} in let new_summary = {summary with stats; payloads} in
Summary.store new_summary ; remove_active callee_pname ; log_elapsed_time () ; new_summary Summary.OnDisk.store new_summary ;
remove_active callee_pname ;
log_elapsed_time () ;
new_summary
in in
let old_state = save_global_state () in let old_state = save_global_state () in
let initial_callee_summary = preprocess () in let initial_callee_summary = preprocess () in
@ -293,7 +296,7 @@ let register_callee ?caller_summary callee_pname =
let get_proc_desc callee_pname = let get_proc_desc callee_pname =
IList.force_until_first_some IList.force_until_first_some
[ lazy (Procdesc.load callee_pname) [ lazy (Procdesc.load callee_pname)
; lazy (Option.map ~f:Summary.get_proc_desc (Summary.get callee_pname)) ; lazy (Option.map ~f:Summary.get_proc_desc (Summary.OnDisk.get callee_pname))
; lazy (Topl.get_proc_desc callee_pname) ] ; lazy (Topl.get_proc_desc callee_pname) ]
@ -318,10 +321,10 @@ let analyze_proc ?caller_summary callee_pname callee_pdesc should_be_analyzed =
callee_pdesc) callee_pdesc)
, true ) , true )
| None -> | None ->
(Summary.get callee_pname, true) (Summary.OnDisk.get callee_pname, true)
else ( else (
EventLogger.log_skipped_pname (F.asprintf "%a" Typ.Procname.pp callee_pname) ; EventLogger.log_skipped_pname (F.asprintf "%a" Typ.Procname.pp callee_pname) ;
(Summary.get callee_pname, true) ) (Summary.OnDisk.get callee_pname, true) )
in in
if update_memcached then memcache_set callee_pname callee_summary_option ; if update_memcached then memcache_set callee_pname callee_summary_option ;
Typ.Procname.Hash.add cache callee_pname callee_summary_option ; Typ.Procname.Hash.add cache callee_pname callee_summary_option ;

@ -209,7 +209,7 @@ let do_funptr_sub summary tenv =
let do_preanalysis pdesc tenv = let do_preanalysis pdesc tenv =
let summary = Summary.reset pdesc in let summary = Summary.OnDisk.reset pdesc in
if if
Config.function_pointer_specialization Config.function_pointer_specialization
&& not (Typ.Procname.is_java (Procdesc.get_proc_name pdesc)) && not (Typ.Procname.is_java (Procdesc.get_proc_name pdesc))

@ -69,7 +69,7 @@ let curr_html_formatter = ref F.std_formatter
(** Return true if the node was visited during analysis *) (** Return true if the node was visited during analysis *)
let is_visited node = let is_visited node =
match Summary.get (Procdesc.Node.get_proc_name node) with match Summary.OnDisk.get (Procdesc.Node.get_proc_name node) with
| None -> | None ->
false false
| Some summary -> | Some summary ->
@ -182,7 +182,7 @@ end = struct
[]) [])
linenum ; linenum ;
pp_node_link_seq [] ~description:true fmt nodes ; pp_node_link_seq [] ~description:true fmt nodes ;
( match Summary.get pname with ( match Summary.OnDisk.get pname with
| None -> | None ->
() ()
| Some summary -> | Some summary ->
@ -230,7 +230,7 @@ end = struct
Hashtbl.replace table_nodes_at_linenum lnum (n :: curr_nodes) Hashtbl.replace table_nodes_at_linenum lnum (n :: curr_nodes)
in in
List.iter ~f:process_node (Procdesc.get_nodes proc_desc) ; List.iter ~f:process_node (Procdesc.get_nodes proc_desc) ;
match Summary.get proc_name with match Summary.OnDisk.get proc_name with
| None -> | None ->
() ()
| Some summary -> | Some summary ->
@ -259,7 +259,7 @@ end = struct
| Procdesc.Node.Start_node -> | Procdesc.Node.Start_node ->
let proc_name = Procdesc.Node.get_proc_name n in let proc_name = Procdesc.Node.get_proc_name n in
let proc_name_escaped = Escape.escape_xml (Typ.Procname.to_string proc_name) in let proc_name_escaped = Escape.escape_xml (Typ.Procname.to_string proc_name) in
if Summary.get proc_name |> Option.is_some then ( if Summary.OnDisk.get proc_name |> Option.is_some then (
F.pp_print_char fmt ' ' ; F.pp_print_char fmt ' ' ;
let label = F.asprintf "summary for %s" proc_name_escaped in let label = F.asprintf "summary for %s" proc_name_escaped in
Io_infer.Html.pp_proc_link [fname_encoding] proc_name fmt label ) Io_infer.Html.pp_proc_link [fname_encoding] proc_name fmt label )

@ -59,7 +59,7 @@ let log_issue_from_summary severity summary ~node ~session ~loc ~ltr ?extras exn
let log_issue_deprecated_using_state severity proc_name ?node ?loc ?ltr exn = let log_issue_deprecated_using_state severity proc_name ?node ?loc ?ltr exn =
if !BiabductionConfig.footprint then if !BiabductionConfig.footprint then
match Summary.get proc_name with match Summary.OnDisk.get proc_name with
| Some summary -> | Some summary ->
let node = let node =
let node = match node with None -> State.get_node_exn () | Some node -> node in let node = match node with None -> State.get_node_exn () | Some node -> node in

@ -519,7 +519,7 @@ let method_exists right_proc_name methods =
| Some attrs -> | Some attrs ->
attrs.ProcAttributes.is_defined attrs.ProcAttributes.is_defined
| None -> | None ->
Summary.has_model right_proc_name Summary.OnDisk.has_model right_proc_name
let resolve_method tenv class_name proc_name = let resolve_method tenv class_name proc_name =
@ -1125,7 +1125,7 @@ let resolve_and_analyze_clang current_summary tenv prop_r n_actual_params callee
(* to be extended to other methods *) (* to be extended to other methods *)
then then
try try
let has_clang_model = Summary.has_model callee_pname in let has_clang_model = Summary.OnDisk.has_model callee_pname in
let resolve_and_analyze_result = let resolve_and_analyze_result =
resolve_and_analyze tenv ~caller_summary:current_summary ~has_clang_model prop_r resolve_and_analyze tenv ~caller_summary:current_summary ~has_clang_model prop_r
n_actual_params callee_pname call_flags n_actual_params callee_pname call_flags
@ -1721,7 +1721,7 @@ and unknown_or_scan_call ~is_scan ~reason ret_typ ret_annots
let callee_loc_opt = let callee_loc_opt =
Option.map Option.map
~f:(fun attributes -> attributes.ProcAttributes.loc) ~f:(fun attributes -> attributes.ProcAttributes.loc)
(Summary.proc_resolve_attributes callee_pname) (Summary.OnDisk.proc_resolve_attributes callee_pname)
in in
let skip_path = Paths.Path.add_skipped_call path callee_pname reason callee_loc_opt in let skip_path = Paths.Path.add_skipped_call path callee_pname reason callee_loc_opt in
[(prop_with_undef_attr, skip_path)] [(prop_with_undef_attr, skip_path)]
@ -1763,7 +1763,7 @@ and check_variadic_sentinel ?(fails_on_nil = false) n_formals (sentinel, null_po
and check_variadic_sentinel_if_present ({Builtin.prop_; path; proc_name} as builtin_args) = and check_variadic_sentinel_if_present ({Builtin.prop_; path; proc_name} as builtin_args) =
match Summary.proc_resolve_attributes proc_name with match Summary.OnDisk.proc_resolve_attributes proc_name with
| None -> | None ->
[(prop_, path)] [(prop_, path)]
| Some callee_attributes -> ( | Some callee_attributes -> (

@ -834,7 +834,7 @@ let prop_set_exn tenv pname prop se_exn =
(** Include a subtrace for a procedure call if the callee is not a model. *) (** Include a subtrace for a procedure call if the callee is not a model. *)
let include_subtrace callee_pname = let include_subtrace callee_pname =
match Summary.proc_resolve_attributes callee_pname with match Summary.OnDisk.proc_resolve_attributes callee_pname with
| Some attrs -> | Some attrs ->
(not attrs.ProcAttributes.is_model) (not attrs.ProcAttributes.is_model)
&& SourceFile.is_under_project_root attrs.ProcAttributes.loc.Location.file && SourceFile.is_under_project_root attrs.ProcAttributes.loc.Location.file

@ -96,9 +96,8 @@ let analysis cfg tenv =
let f proc_name pdesc domain = let f proc_name pdesc domain =
if Procdesc.is_defined pdesc && Typ.Procname.is_constructor proc_name then if Procdesc.is_defined pdesc && Typ.Procname.is_constructor proc_name then
match match
FieldsAssignedInConstructorsChecker.compute_post FieldsAssignedInConstructorsChecker.compute_post ~initial
(ProcData.make (Summary.reset pdesc) tenv (Ident.Hash.create 10)) (ProcData.make (Summary.OnDisk.reset pdesc) tenv (Ident.Hash.create 10))
~initial
with with
| Some new_domain -> | Some new_domain ->
FieldsAssignedInConstructors.union new_domain domain FieldsAssignedInConstructors.union new_domain domain

@ -51,7 +51,8 @@ let is_allocator tenv pname =
let check_attributes check tenv pname = let check_attributes check tenv pname =
PatternMatch.check_class_attributes check tenv pname PatternMatch.check_class_attributes check tenv pname
|| Annotations.pname_has_return_annot pname ~attrs_of_pname:Summary.proc_resolve_attributes check || Annotations.pname_has_return_annot pname
~attrs_of_pname:Summary.OnDisk.proc_resolve_attributes check
let method_overrides is_annotated tenv pname = let method_overrides is_annotated tenv pname =

@ -41,7 +41,7 @@ let protect ~f ~recover ~pp_context (trans_unit_ctx : CFrontend_config.translati
module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFrontend = struct module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFrontend = struct
let model_exists procname = (not Config.models_mode) && Summary.has_model procname let model_exists procname = (not Config.models_mode) && Summary.OnDisk.has_model procname
(** Translates the method/function's body into nodes of the cfg. *) (** Translates the method/function's body into nodes of the cfg. *)
let add_method ?(is_destructor_wrapper = false) trans_unit_ctx tenv cfg class_decl_opt procname let add_method ?(is_destructor_wrapper = false) trans_unit_ctx tenv cfg class_decl_opt procname

@ -524,7 +524,7 @@ let analyze_procedure {Callbacks.exe_env; summary} =
let initial = let initial =
let threads = let threads =
if if
runs_on_ui_thread ~attrs_of_pname:Summary.proc_resolve_attributes tenv proc_desc runs_on_ui_thread ~attrs_of_pname:Summary.OnDisk.proc_resolve_attributes tenv proc_desc
|> Option.is_some |> Option.is_some
|| is_thread_confined_method tenv proc_desc || is_thread_confined_method tenv proc_desc
then ThreadsDomain.AnyThreadButSelf then ThreadsDomain.AnyThreadButSelf

@ -155,7 +155,8 @@ let should_skip =
let has_return_annot predicate pn = let has_return_annot predicate pn =
Annotations.pname_has_return_annot pn ~attrs_of_pname:Summary.proc_resolve_attributes predicate Annotations.pname_has_return_annot pn ~attrs_of_pname:Summary.OnDisk.proc_resolve_attributes
predicate
let is_functional pname = let is_functional pname =
@ -342,8 +343,8 @@ let is_thread_safe_class pname tenv =
let is_thread_safe_method pname tenv = let is_thread_safe_method pname tenv =
find_method_or_override_annotated ~attrs_of_pname:Summary.proc_resolve_attributes is_thread_safe find_method_or_override_annotated ~attrs_of_pname:Summary.OnDisk.proc_resolve_attributes
pname tenv is_thread_safe pname tenv
|> Option.is_some |> Option.is_some

@ -159,8 +159,8 @@ let analyze_procedure {Callbacks.exe_env; summary} =
StarvationDomain.acquire tenv StarvationDomain.bottom loc (Option.to_list lock) StarvationDomain.acquire tenv StarvationDomain.bottom loc (Option.to_list lock)
in in
let initial = let initial =
ConcurrencyModels.runs_on_ui_thread ~attrs_of_pname:Summary.proc_resolve_attributes tenv ConcurrencyModels.runs_on_ui_thread ~attrs_of_pname:Summary.OnDisk.proc_resolve_attributes
proc_desc tenv proc_desc
|> Option.value_map ~default:initial ~f:(StarvationDomain.set_on_ui_thread initial loc) |> Option.value_map ~default:initial ~f:(StarvationDomain.set_on_ui_thread initial loc)
in in
let filter_blocks = let filter_blocks =

@ -41,7 +41,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
~f:(fun attributes -> ~f:(fun attributes ->
ClangMethodKind.equal attributes.ProcAttributes.clang_method_kind ClangMethodKind.equal attributes.ProcAttributes.clang_method_kind
ClangMethodKind.CPP_INSTANCE ) ClangMethodKind.CPP_INSTANCE )
(Summary.proc_resolve_attributes callee_pname) (Summary.OnDisk.proc_resolve_attributes callee_pname)
let is_objc_instance_method callee_pname = let is_objc_instance_method callee_pname =
@ -49,7 +49,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
~f:(fun attributes -> ~f:(fun attributes ->
ClangMethodKind.equal attributes.ProcAttributes.clang_method_kind ClangMethodKind.equal attributes.ProcAttributes.clang_method_kind
ClangMethodKind.OBJC_INSTANCE ) ClangMethodKind.OBJC_INSTANCE )
(Summary.proc_resolve_attributes callee_pname) (Summary.OnDisk.proc_resolve_attributes callee_pname)
let is_blacklisted_method : Typ.Procname.t -> bool = let is_blacklisted_method : Typ.Procname.t -> bool =
@ -91,7 +91,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let lookup_local_attributes = function let lookup_local_attributes = function
| Typ.Procname.Java _ as pname -> | Typ.Procname.Java _ as pname ->
(* Looking up the attribute according to the classpath *) (* Looking up the attribute according to the classpath *)
Summary.proc_resolve_attributes pname Summary.OnDisk.proc_resolve_attributes pname
| pname -> | pname ->
(* Looking up the attributes locally, i.e. either from the file of from the includes *) (* Looking up the attributes locally, i.e. either from the file of from the includes *)
Option.map ~f:Procdesc.get_attributes (Ondemand.get_proc_desc pname) Option.map ~f:Procdesc.get_attributes (Ondemand.get_proc_desc pname)

@ -754,7 +754,7 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p
in in
let resolved_ret_ = let resolved_ret_ =
let ret_ia, ret_typ = callee_annotated_signature.AnnotatedSignature.ret in let ret_ia, ret_typ = callee_annotated_signature.AnnotatedSignature.ret in
let is_library = Summary.proc_is_library callee_attributes in let is_library = Summary.OnDisk.proc_is_library callee_attributes in
let origin = let origin =
TypeOrigin.Proc TypeOrigin.Proc
{ TypeOrigin.pname= callee_pname { TypeOrigin.pname= callee_pname

@ -154,7 +154,7 @@ let tests =
; ( "sink without source not tracked" ; ( "sink without source not tracked"
, [assign_to_non_source "ret_id"; call_sink "ret_id"; assert_empty] ) ] , [assign_to_non_source "ret_id"; call_sink "ret_id"; assert_empty] ) ]
|> TestInterpreter.create_tests ~pp_opt:pp_sparse |> TestInterpreter.create_tests ~pp_opt:pp_sparse
{formal_map= FormalMap.empty; summary= Summary.dummy} {formal_map= FormalMap.empty; summary= Summary.OnDisk.dummy}
~initial:(MockTaintAnalysis.Domain.bottom, Bindings.empty) ~initial:(MockTaintAnalysis.Domain.bottom, Bindings.empty)
in in
"taint_test_suite" >::: test_list "taint_test_suite" >::: test_list

@ -243,7 +243,7 @@ struct
let exit_node = create_node Procdesc.Node.Exit_node [] in let exit_node = create_node Procdesc.Node.Exit_node [] in
set_succs last_node [exit_node] ~exn_handlers:no_exn_handlers ; set_succs last_node [exit_node] ~exn_handlers:no_exn_handlers ;
Procdesc.set_exit_node pdesc exit_node ; Procdesc.set_exit_node pdesc exit_node ;
(Summary.reset pdesc, assert_map) (Summary.OnDisk.reset pdesc, assert_map)
let create_test test_program extras ~initial pp_opt test_pname _ = let create_test test_program extras ~initial pp_opt test_pname _ =

Loading…
Cancel
Save