|
|
|
@ -698,10 +698,16 @@ let resolve_args prop args =
|
|
|
|
|
args
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type resolve_and_analyze_result =
|
|
|
|
|
{ resolved_pname: Typ.Procname.t
|
|
|
|
|
; resolved_procdesc_opt: Procdesc.t option
|
|
|
|
|
; resolved_summary_opt: Summary.t option
|
|
|
|
|
; dynamic_dispatch_status: EventLogger.dynamic_dispatch option }
|
|
|
|
|
|
|
|
|
|
(** Resolve the procedure name and run the analysis of the resolved procedure
|
|
|
|
|
if not already analyzed *)
|
|
|
|
|
let resolve_and_analyze tenv ~caller_pdesc ?(has_clang_model= false) prop args callee_proc_name
|
|
|
|
|
call_flags : Typ.Procname.t * (Procdesc.t option * Summary.t option) =
|
|
|
|
|
call_flags : resolve_and_analyze_result =
|
|
|
|
|
(* TODO (#15748878): Fix conflict with method overloading by encoding in the procedure name
|
|
|
|
|
whether the method is defined or generated by the specialization *)
|
|
|
|
|
let analyze_ondemand resolved_pname : Procdesc.t option * Summary.t option =
|
|
|
|
@ -709,7 +715,7 @@ let resolve_and_analyze tenv ~caller_pdesc ?(has_clang_model= false) prop args c
|
|
|
|
|
( Ondemand.get_proc_desc callee_proc_name
|
|
|
|
|
, Ondemand.analyze_proc_name ~caller_pdesc callee_proc_name )
|
|
|
|
|
else
|
|
|
|
|
(* Create the type sprecialized procedure description and analyze it directly *)
|
|
|
|
|
(* Create the type specialized procedure description and analyze it directly *)
|
|
|
|
|
let analyze specialized_pdesc = Ondemand.analyze_proc_desc ~caller_pdesc specialized_pdesc in
|
|
|
|
|
let resolved_proc_desc_option =
|
|
|
|
|
match Ondemand.get_proc_desc resolved_pname with
|
|
|
|
@ -739,7 +745,12 @@ let resolve_and_analyze tenv ~caller_pdesc ?(has_clang_model= false) prop args c
|
|
|
|
|
(resolved_proc_desc_option, Option.bind resolved_proc_desc_option ~f:analyze)
|
|
|
|
|
in
|
|
|
|
|
let resolved_pname = resolve_pname ~caller_pdesc tenv prop args callee_proc_name call_flags in
|
|
|
|
|
(resolved_pname, analyze_ondemand resolved_pname)
|
|
|
|
|
let dynamic_dispatch_status =
|
|
|
|
|
if Typ.Procname.equal callee_proc_name resolved_pname then None
|
|
|
|
|
else Some EventLogger.Dynamic_dispatch_successful
|
|
|
|
|
in
|
|
|
|
|
let resolved_procdesc_opt, resolved_summary_opt = analyze_ondemand resolved_pname in
|
|
|
|
|
{resolved_pname; resolved_procdesc_opt; resolved_summary_opt; dynamic_dispatch_status}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** recognize calls to the constructor java.net.URL and splits the argument string
|
|
|
|
@ -1114,7 +1125,10 @@ let resolve_and_analyze_no_dynamic_dispatch current_pdesc tenv prop_r n_actual_p
|
|
|
|
|
let resolved_summary_opt =
|
|
|
|
|
Ondemand.analyze_proc_name ~caller_pdesc:current_pdesc resolved_pname
|
|
|
|
|
in
|
|
|
|
|
(resolved_pname, (Ondemand.get_proc_desc resolved_pname, resolved_summary_opt))
|
|
|
|
|
{ resolved_pname
|
|
|
|
|
; resolved_procdesc_opt= Ondemand.get_proc_desc resolved_pname
|
|
|
|
|
; resolved_summary_opt
|
|
|
|
|
; dynamic_dispatch_status= None }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let resolve_and_analyze_clang current_pdesc tenv prop_r n_actual_params callee_pname call_flags =
|
|
|
|
@ -1126,7 +1140,7 @@ let resolve_and_analyze_clang current_pdesc tenv prop_r n_actual_params callee_p
|
|
|
|
|
then
|
|
|
|
|
try
|
|
|
|
|
let has_clang_model = Summary.has_model callee_pname in
|
|
|
|
|
let resolved_pname, (resolved_pdesc_opt, resolved_summary_opt) =
|
|
|
|
|
let resolve_and_analyze_result =
|
|
|
|
|
resolve_and_analyze tenv ~caller_pdesc:current_pdesc ~has_clang_model prop_r
|
|
|
|
|
n_actual_params callee_pname call_flags
|
|
|
|
|
in
|
|
|
|
@ -1134,7 +1148,7 @@ let resolve_and_analyze_clang current_pdesc tenv prop_r n_actual_params callee_p
|
|
|
|
|
because we don't have the correct fields in the tenv.
|
|
|
|
|
In that case, default to the non-specialized spec for the model. *)
|
|
|
|
|
let clang_model_specialized_failure =
|
|
|
|
|
match resolved_summary_opt with
|
|
|
|
|
match resolve_and_analyze_result.resolved_summary_opt with
|
|
|
|
|
| Some summary when has_clang_model ->
|
|
|
|
|
List.is_empty (Tabulation.get_specs_from_payload summary)
|
|
|
|
|
| None ->
|
|
|
|
@ -1143,12 +1157,21 @@ let resolve_and_analyze_clang current_pdesc tenv prop_r n_actual_params callee_p
|
|
|
|
|
false
|
|
|
|
|
in
|
|
|
|
|
if clang_model_specialized_failure then
|
|
|
|
|
let result =
|
|
|
|
|
resolve_and_analyze_no_dynamic_dispatch current_pdesc tenv prop_r n_actual_params
|
|
|
|
|
callee_pname call_flags
|
|
|
|
|
in
|
|
|
|
|
{ result with
|
|
|
|
|
dynamic_dispatch_status= Some EventLogger.Dynamic_dispatch_model_specialization_failure
|
|
|
|
|
}
|
|
|
|
|
else resolve_and_analyze_result
|
|
|
|
|
with Procdesc.UnmatchedParameters ->
|
|
|
|
|
let result =
|
|
|
|
|
resolve_and_analyze_no_dynamic_dispatch current_pdesc tenv prop_r n_actual_params
|
|
|
|
|
callee_pname call_flags
|
|
|
|
|
else (resolved_pname, (resolved_pdesc_opt, resolved_summary_opt))
|
|
|
|
|
with Procdesc.UnmatchedParameters ->
|
|
|
|
|
resolve_and_analyze_no_dynamic_dispatch current_pdesc tenv prop_r n_actual_params
|
|
|
|
|
callee_pname call_flags
|
|
|
|
|
in
|
|
|
|
|
{ result with
|
|
|
|
|
dynamic_dispatch_status= Some EventLogger.Dynamic_dispatch_parameters_arguments_mismatch }
|
|
|
|
|
else
|
|
|
|
|
resolve_and_analyze_no_dynamic_dispatch current_pdesc tenv prop_r n_actual_params callee_pname
|
|
|
|
|
call_flags
|
|
|
|
@ -1285,11 +1308,12 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p
|
|
|
|
|
skip_call ~reason norm_prop path skipped_pname ret_annots loc ret_id_typ ret_type
|
|
|
|
|
norm_args
|
|
|
|
|
in
|
|
|
|
|
let resolved_pname, (_, resolved_summary_opt) =
|
|
|
|
|
let resolve_and_analyze_result =
|
|
|
|
|
resolve_and_analyze tenv ~caller_pdesc:current_pdesc norm_prop norm_args callee_pname
|
|
|
|
|
call_flags
|
|
|
|
|
in
|
|
|
|
|
match resolved_summary_opt with
|
|
|
|
|
let resolved_pname = resolve_and_analyze_result.resolved_pname in
|
|
|
|
|
match resolve_and_analyze_result.resolved_summary_opt with
|
|
|
|
|
| None ->
|
|
|
|
|
let ret_typ = Typ.Procname.Java.get_return_typ callee_pname_java in
|
|
|
|
|
let ret_annots = load_ret_annots callee_pname in
|
|
|
|
@ -1351,10 +1375,14 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p
|
|
|
|
|
(call_args prop_r callee_pname n_extended_actual_params ret_id_typ loc)
|
|
|
|
|
| None ->
|
|
|
|
|
(* Generic fun call with known name *)
|
|
|
|
|
let resolved_pname, (resolved_pdesc_opt, resolved_summary_opt) =
|
|
|
|
|
let resolve_and_analyze_result =
|
|
|
|
|
resolve_and_analyze_clang current_pdesc tenv prop_r n_actual_params callee_pname
|
|
|
|
|
call_flags
|
|
|
|
|
in
|
|
|
|
|
let resolved_pname = resolve_and_analyze_result.resolved_pname in
|
|
|
|
|
let resolved_pdesc_opt = resolve_and_analyze_result.resolved_procdesc_opt in
|
|
|
|
|
let resolved_summary_opt = resolve_and_analyze_result.resolved_summary_opt in
|
|
|
|
|
let dynamic_dispatch_status = resolve_and_analyze_result.dynamic_dispatch_status in
|
|
|
|
|
Logging.d_strln ("Original callee " ^ Typ.Procname.to_unique_id callee_pname) ;
|
|
|
|
|
Logging.d_strln ("Resolved callee " ^ Typ.Procname.to_unique_id resolved_pname) ;
|
|
|
|
|
let sentinel_result =
|
|
|
|
@ -1416,7 +1444,7 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p
|
|
|
|
|
skip_call ~reason prop path resolved_pname ret_annots loc ret_id_typ
|
|
|
|
|
(snd ret_id_typ) n_actual_params )
|
|
|
|
|
| None ->
|
|
|
|
|
proc_call exe_env
|
|
|
|
|
proc_call ?dynamic_dispatch:dynamic_dispatch_status exe_env
|
|
|
|
|
(Option.value_exn resolved_summary_opt)
|
|
|
|
|
(call_args prop resolved_pname n_actual_params ret_id_typ loc)
|
|
|
|
|
in
|
|
|
|
@ -1825,7 +1853,7 @@ and sym_exec_alloc_model exe_env pname ret_typ tenv ret_id_typ pdesc loc prop pa
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** Perform symbolic execution for a function call *)
|
|
|
|
|
and proc_call exe_env callee_summary
|
|
|
|
|
and proc_call ?dynamic_dispatch exe_env callee_summary
|
|
|
|
|
{Builtin.pdesc; tenv; prop_= pre; path; ret_id_typ; args= actual_pars; loc} =
|
|
|
|
|
let caller_pname = Procdesc.get_proc_name pdesc in
|
|
|
|
|
let callee_attrs = Summary.get_attributes callee_summary in
|
|
|
|
@ -1872,11 +1900,11 @@ and proc_call exe_env callee_summary
|
|
|
|
|
| Language.Clang, ProcAttributes.OBJC_INSTANCE ->
|
|
|
|
|
handle_objc_instance_method_call actual_pars actual_params pre tenv (fst ret_id_typ) pdesc
|
|
|
|
|
callee_pname loc path
|
|
|
|
|
(Tabulation.exe_function_call exe_env callee_summary)
|
|
|
|
|
(Tabulation.exe_function_call ?dynamic_dispatch exe_env callee_summary)
|
|
|
|
|
| _ ->
|
|
|
|
|
(* non-objective-c method call. Standard tabulation *)
|
|
|
|
|
Tabulation.exe_function_call exe_env callee_summary tenv (fst ret_id_typ) pdesc callee_pname
|
|
|
|
|
loc actual_params pre path
|
|
|
|
|
Tabulation.exe_function_call ?dynamic_dispatch exe_env callee_summary tenv (fst ret_id_typ)
|
|
|
|
|
pdesc callee_pname loc actual_params pre path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** perform symbolic execution for a single prop, and check for junk *)
|
|
|
|
|