|
|
|
@ -9,8 +9,10 @@
|
|
|
|
|
open! IStd
|
|
|
|
|
module L = Logging
|
|
|
|
|
|
|
|
|
|
(** add instructions to perform abstraction *)
|
|
|
|
|
let add_abstraction_instructions pdesc =
|
|
|
|
|
(** add Abstract instructions into the IR to give hints about when abstraction should be
|
|
|
|
|
performed *)
|
|
|
|
|
module AddAbstractionInstructions = struct
|
|
|
|
|
let process pdesc =
|
|
|
|
|
let open Procdesc in
|
|
|
|
|
(* true if there is a succ node s.t.: it is an exit node, or the succ of >1 nodes *)
|
|
|
|
|
let converging_node node =
|
|
|
|
@ -32,8 +34,11 @@ let add_abstraction_instructions pdesc =
|
|
|
|
|
if node_requires_abstraction node then Node.append_instrs node [Sil.Metadata (Abstract loc)]
|
|
|
|
|
in
|
|
|
|
|
Procdesc.iter_nodes do_node pdesc
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** perform liveness analysis and insert Nullify/Remove_temps instructions into the IR to make it
|
|
|
|
|
easy for analyses to do abstract garbage collection *)
|
|
|
|
|
module Liveness = struct
|
|
|
|
|
module BackwardCfg = ProcCfg.Backward (ProcCfg.Exceptional)
|
|
|
|
|
module LivenessAnalysis =
|
|
|
|
|
AbstractInterpreter.MakeRPO (Liveness.PreAnalysisTransferFunctions (BackwardCfg))
|
|
|
|
@ -183,36 +188,34 @@ let add_nullify_instrs summary tenv liveness_inv_map =
|
|
|
|
|
if not (AddressTaken.Domain.is_empty address_taken_vars) then
|
|
|
|
|
let exit_node = ProcCfg.Exceptional.exit_node nullify_proc_cfg in
|
|
|
|
|
let exit_loc = Procdesc.Node.get_last_loc exit_node in
|
|
|
|
|
prepend_node_nullify_instructions exit_loc (AddressTaken.Domain.elements address_taken_vars) []
|
|
|
|
|
prepend_node_nullify_instructions exit_loc
|
|
|
|
|
(AddressTaken.Domain.elements address_taken_vars)
|
|
|
|
|
[]
|
|
|
|
|
|> Procdesc.Node.append_instrs exit_node
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** perform liveness analysis and insert Nullify/Remove_temps instructions into the IR to make it
|
|
|
|
|
easy for analyses to do abstract garbage collection *)
|
|
|
|
|
let do_liveness summary tenv =
|
|
|
|
|
let process summary tenv =
|
|
|
|
|
let liveness_proc_cfg = BackwardCfg.from_pdesc (Summary.get_proc_desc summary) in
|
|
|
|
|
let initial = Liveness.Domain.empty in
|
|
|
|
|
let liveness_inv_map =
|
|
|
|
|
LivenessAnalysis.exec_cfg liveness_proc_cfg (ProcData.make_default summary tenv) ~initial
|
|
|
|
|
in
|
|
|
|
|
add_nullify_instrs summary tenv liveness_inv_map
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** add Abstract instructions into the IR to give hints about when abstraction should be
|
|
|
|
|
performed *)
|
|
|
|
|
let do_abstraction pdesc = add_abstraction_instructions pdesc
|
|
|
|
|
|
|
|
|
|
let do_funptr_sub summary tenv =
|
|
|
|
|
module FunctionPointerSubstitution = struct
|
|
|
|
|
let process summary tenv =
|
|
|
|
|
let updated = FunctionPointers.substitute_function_pointers summary tenv in
|
|
|
|
|
let pdesc = Summary.get_proc_desc summary in
|
|
|
|
|
if updated then Attributes.store ~proc_desc:(Some pdesc) (Procdesc.get_attributes pdesc)
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
let do_preanalysis pdesc tenv =
|
|
|
|
|
let summary = Summary.OnDisk.reset pdesc in
|
|
|
|
|
if
|
|
|
|
|
Config.function_pointer_specialization
|
|
|
|
|
&& not (Typ.Procname.is_java (Procdesc.get_proc_name pdesc))
|
|
|
|
|
then do_funptr_sub summary tenv ;
|
|
|
|
|
do_liveness summary tenv ;
|
|
|
|
|
do_abstraction pdesc
|
|
|
|
|
then FunctionPointerSubstitution.process summary tenv ;
|
|
|
|
|
Liveness.process summary tenv ;
|
|
|
|
|
AddAbstractionInstructions.process pdesc ;
|
|
|
|
|
()
|
|
|
|
|