@ -189,11 +189,8 @@ let conservatively_initialize_args arg_values ({AbductiveDomain.post} as astate)
AbstractValue . Set . fold AbductiveDomain . initialize reachable_values astate
AbstractValue . Set . fold AbductiveDomain . initialize reachable_values astate
let call tenv ~ caller_proc_desc ~ ( callee_data : ( Procdesc . t * PulseSummary . t ) option ) call_loc
let call_aux tenv caller_proc_desc call_loc callee_pname ret actuals callee_proc_desc exec_states
callee_pname ~ ret ~ actuals ~ formals_opt ( astate : AbductiveDomain . t ) =
( astate : AbductiveDomain . t ) =
let get_arg_values () = List . map actuals ~ f : ( fun ( ( value , _ ) , _ ) -> value ) in
match callee_data with
| Some ( callee_proc_desc , exec_states ) ->
let formals =
let formals =
Procdesc . get_formals callee_proc_desc
Procdesc . get_formals callee_proc_desc
| > List . map ~ f : ( fun ( mangled , _ ) -> Pvar . mk mangled callee_pname | > Var . of_pvar )
| > List . map ~ f : ( fun ( mangled , _ ) -> Pvar . mk mangled callee_pname | > Var . of_pvar )
@ -221,9 +218,7 @@ let call tenv ~caller_proc_desc ~(callee_data : (Procdesc.t * PulseSummary.t) op
L . d_printfln " Will keep at most one disjunct because %a is in blacklist " Procname . pp
L . d_printfln " Will keep at most one disjunct because %a is in blacklist " Procname . pp
callee_pname ;
callee_pname ;
(* call {!AbductiveDomain.PrePost.apply} on each pre/post pair in the summary. *)
(* call {!AbductiveDomain.PrePost.apply} on each pre/post pair in the summary. *)
List . fold ~ init : []
List . fold ~ init : [] exec_states ~ f : ( fun posts callee_exec_state ->
( exec_states :> ExecutionDomain . t list )
~ f : ( fun posts callee_exec_state ->
if should_keep_at_most_one_disjunct && not ( List . is_empty posts ) then posts
if should_keep_at_most_one_disjunct && not ( List . is_empty posts ) then posts
else
else
(* apply all pre/post specs *)
(* apply all pre/post specs *)
@ -236,11 +231,44 @@ let call tenv ~caller_proc_desc ~(callee_data : (Procdesc.t * PulseSummary.t) op
posts
posts
| Sat post ->
| Sat post ->
post :: posts )
post :: posts )
let call tenv ~ caller_proc_desc ~ ( callee_data : ( Procdesc . t * PulseSummary . t ) option ) call_loc
callee_pname ~ ret ~ actuals ~ formals_opt ( astate : AbductiveDomain . t ) =
let get_arg_values () = List . map actuals ~ f : ( fun ( ( value , _ ) , _ ) -> value ) in
(* a special case for objc nil messaging *)
let unknown_objc_nil_messaging astate_unknown procdesc =
let result_unknown =
let < + > astate_unknown =
PulseObjectiveCSummary . append_objc_actual_self_positive procdesc ( List . hd actuals )
astate_unknown
in
astate_unknown
in
let result_unknown_nil =
PulseObjectiveCSummary . mk_objc_method_nil_summary tenv procdesc
( ExecutionDomain . mk_initial tenv procdesc )
| > Option . value_map ~ default : [] ~ f : ( fun nil_summary ->
let < * > nil_astate = nil_summary in
call_aux tenv caller_proc_desc call_loc callee_pname ret actuals procdesc
( [ ContinueProgram nil_astate ] :> ExecutionDomain . t list )
astate )
in
result_unknown @ result_unknown_nil
in
match callee_data with
| Some ( callee_proc_desc , exec_states ) ->
call_aux tenv caller_proc_desc call_loc callee_pname ret actuals callee_proc_desc
( exec_states :> ExecutionDomain . t list )
astate
| None ->
| None ->
(* no spec found for some reason ( unknown function, ... ) *)
(* no spec found for some reason ( unknown function, ... ) *)
L . d_printfln " No spec found for %a@ \n " Procname . pp callee_pname ;
L . d_printfln " No spec found for %a@ \n " Procname . pp callee_pname ;
let astate =
let astate _unknown =
conservatively_initialize_args ( get_arg_values () ) astate
conservatively_initialize_args ( get_arg_values () ) astate
| > unknown_call tenv call_loc ( SkippedKnownCall callee_pname ) ~ ret ~ actuals ~ formals_opt
| > unknown_call tenv call_loc ( SkippedKnownCall callee_pname ) ~ ret ~ actuals ~ formals_opt
in
in
[ Ok ( ContinueProgram astate ) ]
let callee_procdesc_opt = AnalysisCallbacks . get_proc_desc callee_pname in
Option . value_map callee_procdesc_opt
~ default : [ Ok ( ContinueProgram astate_unknown ) ]
~ f : ( unknown_objc_nil_messaging astate_unknown )