@ -250,7 +250,7 @@ module Dom = struct
; config_fields = Fields . widen ~ prev : prev . config_fields ~ next : next . config_fields ~ num_iters }
; config_fields = Fields . widen ~ prev : prev . config_fields ~ next : next . config_fields ~ num_iters }
let to_summary has_call_stmt { unchecked_callees ; unchecked_callees_cond ; config_fields } =
let to_summary ~ has_call_stmt { unchecked_callees ; unchecked_callees_cond ; config_fields } =
{ Summary . unchecked_callees ; unchecked_callees_cond ; has_call_stmt ; config_fields }
{ Summary . unchecked_callees ; unchecked_callees_cond ; has_call_stmt ; config_fields }
@ -327,13 +327,24 @@ module Dom = struct
let call analyze_dependency callee location
let call analyze_dependency callee location
( { config_checks ; field_checks ; unchecked_callees ; unchecked_callees_cond } as astate ) =
( { config_checks ; field_checks ; unchecked_callees ; unchecked_callees_cond } as astate ) =
if ConfigChecks . is_top config_checks then
if ConfigChecks . is_top config_checks then
let callee_summary = analyze_dependency callee in
if
Option . exists callee_summary ~ f : ( fun ( _ , ( _ , ( cost_summary : CostDomain . summary option ) ) ) ->
Option . exists cost_summary ~ f : ( fun ( cost_summary : CostDomain . summary ) ->
let callee_cost = CostDomain . get_operation_cost cost_summary . post in
not ( CostDomain . BasicCost . is_symbolic callee_cost . cost ) ) )
then (* If callee is cheap by heuristics, ignore it. *)
astate
else
let new_unchecked_callees , new_unchecked_callees_cond =
let new_unchecked_callees , new_unchecked_callees_cond =
match analyze_dependency callee with
match callee_summary with
| Some
| Some
( _
( _
, { Summary . unchecked_callees = callee_summary
, ( Some
{ Summary . unchecked_callees = callee_summary
; unchecked_callees_cond = callee_summary_cond
; unchecked_callees_cond = callee_summary_cond
; has_call_stmt } )
; has_call_stmt }
, _ callee_cost_summary ) )
when has_call_stmt ->
when has_call_stmt ->
(* If callee's summary is not leaf, use it. *)
(* If callee's summary is not leaf, use it. *)
( UncheckedCallees . replace_location_by_call location callee_summary
( UncheckedCallees . replace_location_by_call location callee_summary
@ -368,7 +379,7 @@ module TransferFunctions = struct
module CFG = ProcCfg . Normal
module CFG = ProcCfg . Normal
module Domain = Dom
module Domain = Dom
type analysis_data = Summary . t InterproceduralAnalysis . t
type analysis_data = ( Summary . t option * CostDomain . summary option ) InterproceduralAnalysis . t
let is_java_boolean_value_method pname =
let is_java_boolean_value_method pname =
Procname . get_class_name pname | > Option . exists ~ f : ( String . equal " java.lang.Boolean " )
Procname . get_class_name pname | > Option . exists ~ f : ( String . equal " java.lang.Boolean " )
@ -460,4 +471,4 @@ let has_call_stmt proc_desc =
let checker ( { InterproceduralAnalysis . proc_desc } as analysis_data ) =
let checker ( { InterproceduralAnalysis . proc_desc } as analysis_data ) =
Option . map ( Analyzer . compute_post analysis_data ~ initial : Dom . init proc_desc ) ~ f : ( fun astate ->
Option . map ( Analyzer . compute_post analysis_data ~ initial : Dom . init proc_desc ) ~ f : ( fun astate ->
let has_call_stmt = has_call_stmt proc_desc in
let has_call_stmt = has_call_stmt proc_desc in
Dom . to_summary has_call_stmt astate )
Dom . to_summary ~ has_call_stmt astate )