@ -761,8 +761,6 @@ end
module Analyzer = AbstractInterpreter . Make ( ProcCfg . Normal ) ( LowerHil . Make ( TransferFunctions ) )
module Analyzer = AbstractInterpreter . Make ( ProcCfg . Normal ) ( LowerHil . Make ( TransferFunctions ) )
module Interprocedural = AbstractInterpreter . Interprocedural ( Summary )
(* similarly, we assume that immutable classes safely encapsulate their state *)
(* similarly, we assume that immutable classes safely encapsulate their state *)
let is_immutable_collection_class class_name tenv =
let is_immutable_collection_class class_name tenv =
let immutable_collections = [
let immutable_collections = [
@ -871,14 +869,15 @@ let analyze_procedure { Callbacks.proc_desc; tenv; summary; } =
Typ . Procname . is_constructor proc_name | | FbThreadSafety . is_custom_init tenv proc_name in
Typ . Procname . is_constructor proc_name | | FbThreadSafety . is_custom_init tenv proc_name in
let open ThreadSafetyDomain in
let open ThreadSafetyDomain in
(* convert the abstract state to a summary by dropping the id map *)
(* convert the abstract state to a summary by dropping the id map *)
let compute_post ( { ProcData . pdesc ; tenv ; extras ; } as proc_data ) =
if should_analyze_proc proc_desc tenv
if should_analyze_proc pdesc tenv
then
then
begin
begin
if not ( Procdesc . did_preanalysis pdesc ) then Preanal . do_liveness pdesc tenv ;
if not ( Procdesc . did_preanalysis proc_desc ) then Preanal . do_liveness proc_desc tenv ;
let extras = FormalMap . make proc_desc in
let proc_data = ProcData . make proc_desc tenv extras in
let initial =
let initial =
let threads = runs_on_ui_thread pdesc | | is_thread_confined_method tenv pdesc in
let threads = runs_on_ui_thread p roc_ desc | | is_thread_confined_method tenv p roc_ desc in
if is_initializer tenv ( Procdesc . get_proc_name p desc)
if is_initializer tenv ( Procdesc . get_proc_name p roc_ desc)
then
then
let add_owned_formal acc formal_index =
let add_owned_formal acc formal_index =
match FormalMap . get_formal_base formal_index extras with
match FormalMap . get_formal_base formal_index extras with
@ -890,8 +889,8 @@ let analyze_procedure { Callbacks.proc_desc; tenv; summary; } =
(* if a constructer is called via DI, all of its formals will be freshly allocated
(* if a constructer is called via DI, all of its formals will be freshly allocated
and therefore owned . we assume that constructors annotated with @ Inject will only
and therefore owned . we assume that constructors annotated with @ Inject will only
be called via DI or using fresh parameters . * )
be called via DI or using fresh parameters . * )
if Annotations . pdesc_has_return_annot p desc Annotations . ia_is_inject
if Annotations . pdesc_has_return_annot p roc_ desc Annotations . ia_is_inject
then List . mapi ~ f : ( fun i _ -> i ) ( Procdesc . get_formals p desc)
then List . mapi ~ f : ( fun i _ -> i ) ( Procdesc . get_formals p roc_ desc)
else [ 0 ] (* express that the constructor owns [this] *) in
else [ 0 ] (* express that the constructor owns [this] *) in
let attribute_map =
let attribute_map =
List . fold
List . fold
@ -906,18 +905,18 @@ let analyze_procedure { Callbacks.proc_desc; tenv; summary; } =
| Some ( { thumbs_up ; threads ; locks ; accesses ; attribute_map ; } , _ ) ->
| Some ( { thumbs_up ; threads ; locks ; accesses ; attribute_map ; } , _ ) ->
let return_var_ap =
let return_var_ap =
AccessPath . of_pvar
AccessPath . of_pvar
( Pvar . get_ret_pvar ( Procdesc . get_proc_name p desc) )
( Pvar . get_ret_pvar ( Procdesc . get_proc_name p roc_ desc) )
( Procdesc . get_ret_type p desc) in
( Procdesc . get_ret_type p roc_ desc) in
let return_attributes =
let return_attributes =
try AttributeMapDomain . find return_var_ap attribute_map
try AttributeMapDomain . find return_var_ap attribute_map
with Not_found -> AttributeSetDomain . empty in
with Not_found -> AttributeSetDomain . empty in
Some ( thumbs_up , threads , locks , accesses , return_attributes )
let post = thumbs_up , threads , locks , accesses , return_attributes in
Summary . update_summary post summary
| None ->
| None ->
None
summary
end
end
else
else
Some empty_post in
Summary . update_summary empty_post summary
Interprocedural . compute_summary ~ compute_post ~ make_extras : FormalMap . make proc_desc tenv summary
(* we assume two access paths can alias if their access parts are equal ( we ignore the base ) . *)
(* we assume two access paths can alias if their access parts are equal ( we ignore the base ) . *)
let can_alias access_path1 access_path2 =
let can_alias access_path1 access_path2 =