diff --git a/infer/src/IR/Cfg.re b/infer/src/IR/Cfg.re index bc18684b5..7e84a4c0c 100644 --- a/infer/src/IR/Cfg.re +++ b/infer/src/IR/Cfg.re @@ -512,6 +512,11 @@ let module Node = { proc_desc.pd_attributes.ProcAttributes.locals = proc_desc.pd_attributes.ProcAttributes.locals @ new_locals; + /** check or indicate if we have performed preanalysis on the CFG */ + let proc_desc_did_preanalysis proc_desc => proc_desc.pd_attributes.ProcAttributes.did_preanalysis; + let proc_desc_signal_did_preanalysis proc_desc => + proc_desc.pd_attributes.ProcAttributes.did_preanalysis = true; + /** Print extended instructions for the node, highlighting the given subinstruction if present */ let pp_instrs pe0 sub_instrs::sub_instrs instro fmt node => { @@ -784,6 +789,8 @@ let module Procdesc = { let compute_distance_to_exit_node = Node.proc_desc_compute_distance_to_exit_node; let create = Node.proc_desc_create; let remove = Node.proc_desc_remove; + let did_preanalysis = Node.proc_desc_did_preanalysis; + let signal_did_preanalysis = Node.proc_desc_signal_did_preanalysis; let find_from_name = Node.proc_desc_from_name; let get_attributes = Node.proc_desc_get_attributes; let get_err_log = Node.proc_desc_get_err_log; diff --git a/infer/src/IR/Cfg.rei b/infer/src/IR/Cfg.rei index 486189a24..623eed1d9 100644 --- a/infer/src/IR/Cfg.rei +++ b/infer/src/IR/Cfg.rei @@ -41,6 +41,12 @@ let module Procdesc: { /** Create a procdesc */ let create: cfg => ProcAttributes.t => t; + /** true if we ran the preanalysis on the CFG associated with [t] */ + let did_preanalysis: t => bool; + + /** indicate that we have performed preanalysis on the CFG assoociated with [t] */ + let signal_did_preanalysis: t => unit; + /** [remove cfg name remove_nodes] remove the procdesc [name] from the control flow graph [cfg]. */ /** It also removes all the nodes from the procedure from the cfg if remove_nodes is true */ diff --git a/infer/src/IR/ProcAttributes.re b/infer/src/IR/ProcAttributes.re index cf4904f3b..f70a85273 100644 --- a/infer/src/IR/ProcAttributes.re +++ b/infer/src/IR/ProcAttributes.re @@ -26,6 +26,7 @@ type t = { access: PredSymb.access, /** visibility access */ captured: list (Mangled.t, Typ.t), /** name and type of variables captured in blocks */ mutable changed: bool, /** true if proc has changed since last analysis */ + mutable did_preanalysis: bool, /** true if we performed preanalysis on the CFG for this proc */ err_log: Errlog.t, /** Error log for the procedure */ exceptions: list string, /** exceptions thrown by the procedure */ formals: list (Mangled.t, Typ.t), /** name and type of formal parameters */ @@ -53,6 +54,7 @@ let default proc_name language => { access: PredSymb.Default, captured: [], changed: true, + did_preanalysis: false, err_log: Errlog.empty (), exceptions: [], formals: [], diff --git a/infer/src/IR/ProcAttributes.rei b/infer/src/IR/ProcAttributes.rei index e44290426..541195545 100644 --- a/infer/src/IR/ProcAttributes.rei +++ b/infer/src/IR/ProcAttributes.rei @@ -20,6 +20,7 @@ type t = { access: PredSymb.access, /** visibility access */ captured: list (Mangled.t, Typ.t), /** name and type of variables captured in blocks */ mutable changed: bool, /** true if proc has changed since last analysis */ + mutable did_preanalysis: bool, /** true if we performed preanalysis on the CFG for this proc */ err_log: Errlog.t, /** Error log for the procedure */ exceptions: list string, /** exceptions thrown by the procedure */ formals: list (Mangled.t, Typ.t), /** name and type of formal parameters */ diff --git a/infer/src/backend/preanal.ml b/infer/src/backend/preanal.ml index ba61e2c05..a4015e268 100644 --- a/infer/src/backend/preanal.ml +++ b/infer/src/backend/preanal.ml @@ -291,11 +291,16 @@ let do_liveness pdesc tenv = LivenessAnalysis.exec_cfg liveness_proc_cfg (ProcData.make_default pdesc tenv) let doit pdesc cg tenv = - if Config.copy_propagation then do_copy_propagation pdesc tenv; - let liveness_inv_map = do_liveness pdesc tenv in - if not (Config.lazy_dynamic_dispatch) && Config.copy_propagation - then remove_dead_frontend_stores pdesc liveness_inv_map; - add_nullify_instrs pdesc tenv liveness_inv_map; - if not Config.lazy_dynamic_dispatch - then add_dispatch_calls pdesc cg tenv; - add_abstraction_instructions pdesc; + if not (Cfg.Procdesc.did_preanalysis pdesc) + then + begin + Cfg.Procdesc.signal_did_preanalysis pdesc; + if Config.copy_propagation then do_copy_propagation pdesc tenv; + let liveness_inv_map = do_liveness pdesc tenv in + if not (Config.lazy_dynamic_dispatch) && Config.copy_propagation + then remove_dead_frontend_stores pdesc liveness_inv_map; + add_nullify_instrs pdesc tenv liveness_inv_map; + if not Config.lazy_dynamic_dispatch + then add_dispatch_calls pdesc cg tenv; + add_abstraction_instructions pdesc; + end diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index 4d907df35..2250f66bd 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -434,6 +434,8 @@ module Make (TraceDomain : QuandarySummary.Trace) = struct (fun formal_map (base, index) -> AccessPath.BaseMap.add base index formal_map) AccessPath.BaseMap.empty formals_with_nums in + + Preanal.doit pdesc dummy_cg tenv; let formals = make_formal_access_paths pdesc in let proc_data = ProcData.make pdesc tenv formals in match Analyzer.compute_post proc_data with @@ -452,7 +454,6 @@ module Make (TraceDomain : QuandarySummary.Trace) = struct if Ondemand.procedure_should_be_analyzed proc_name then begin - Preanal.doit proc_desc dummy_cg tenv; Ondemand.set_callbacks callbacks; analyze_ondemand DB.source_file_empty proc_desc; Ondemand.unset_callbacks ();