Improved/simplified framework for frontend checkers.

Summary:public
Improved/simplified framework for fronend checkers.
Now we have a unique hook from cTrans to run checkers on statements and a unique
hook from cFrontent to run checkers on declarations.
So now when adding a checker we don't have to modify cTrans/cFrontend.

Moreover made more sistematic the way checkers are invoked. This simplify the definition
of checkers and the way we use them.

Code is now simpler.

Reviewed By: jvillard

Differential Revision: D2976589

fb-gh-sync-id: fbe22d4
shipit-source-id: fbe22d4
master
Dino Distefano 9 years ago committed by facebook-github-bot-1
parent 4264e94565
commit be8f25c90b

@ -21,6 +21,8 @@ open CGen_trans
(* Translate one global declaration *) (* Translate one global declaration *)
let rec translate_one_declaration tenv cg cfg parent_dec dec = let rec translate_one_declaration tenv cg cfg parent_dec dec =
let open Clang_ast_t in let open Clang_ast_t in
(* Run the frontend checkers on this declaration *)
CFrontend_errors.run_frontend_checkers_on_decl tenv cg cfg dec;
(* each procedure has different scope: start names from id 0 *) (* each procedure has different scope: start names from id 0 *)
Ident.NameGenerator.reset (); Ident.NameGenerator.reset ();
let info = Clang_ast_proj.get_decl_tuple dec in let info = Clang_ast_proj.get_decl_tuple dec in
@ -56,24 +58,12 @@ let rec translate_one_declaration tenv cg cfg parent_dec dec =
let curr_class = ObjcCategory_decl.get_curr_class_from_category_impl name ocidi in let curr_class = ObjcCategory_decl.get_curr_class_from_category_impl name ocidi in
ignore (ObjcCategory_decl.category_impl_decl CTypes_decl.type_ptr_to_sil_type tenv dec); ignore (ObjcCategory_decl.category_impl_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class decl_list; CMethod_declImpl.process_methods tenv cg cfg curr_class decl_list;
(match Ast_utils.get_decl_opt_with_decl_ref ocidi.Clang_ast_t.ocidi_category_decl with
| Some ObjCCategoryDecl(_, _, cat_decl_list, _, _) ->
let name = CContext.get_curr_class_name curr_class in
let decls = cat_decl_list @ decl_list in
CFrontend_errors.check_for_property_errors cfg cg tenv name decls
| _ -> ())
| ObjCImplementationDecl(_, _, decl_list, _, idi) -> | ObjCImplementationDecl(_, _, decl_list, _, idi) ->
let curr_class = ObjcInterface_decl.get_curr_class_impl idi in let curr_class = ObjcInterface_decl.get_curr_class_impl idi in
let type_ptr_to_sil_type = CTypes_decl.type_ptr_to_sil_type in let type_ptr_to_sil_type = CTypes_decl.type_ptr_to_sil_type in
ignore (ObjcInterface_decl.interface_impl_declaration type_ptr_to_sil_type tenv dec); ignore (ObjcInterface_decl.interface_impl_declaration type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class decl_list; CMethod_declImpl.process_methods tenv cg cfg curr_class decl_list;
(match Ast_utils.get_decl_opt_with_decl_ref idi.Clang_ast_t.oidi_class_interface with
| Some ObjCInterfaceDecl(_, _, cl_decl_list, _, _) ->
let name = CContext.get_curr_class_name curr_class in
let decls = cl_decl_list @ decl_list in
CFrontend_errors.check_for_property_errors cfg cg tenv name decls
| _ -> ())
| CXXMethodDecl (decl_info, _, _, _, _) | CXXMethodDecl (decl_info, _, _, _, _)
| CXXConstructorDecl (decl_info, _, _, _, _) | CXXConstructorDecl (decl_info, _, _, _, _)

@ -8,82 +8,107 @@
*) *)
open CFrontend_utils open CFrontend_utils
open General_utils
(* To create a new checker you should: *)
(* 1. Define a checker function, say my_checker, in this module. *)
(* my_checker should define: *)
(* -a) a condition that determine if the checker fires *)
(* -b) a warning_desc that describes the warning (see warning_desc definition) *)
(* 2. Add your checker to the CFrontend_checkers interface *)
(* 3. Decide in which element of the AST my_checker should be evaluated. *)
(* - If it is a statement then you need to invoke my_checker from *)
(* run_frontend_checkers_on_stmt in CFrontend_error module.*)
(* - If it is a declaration invoke it from run_frontend_checkers_on_decl *)
type warning_desc = {
name : string; (* name for the checker, this will be a kind of bug *)
description : string; (* Description in the error message *)
suggestion : string; (* an optional suggestion or correction *)
loc : Location.t; (* location in the code *)
}
(* Helper functions *)
let property_name_contains_word pname word =
let rexp = Str.regexp_string_case_fold word in
try
Str.search_forward rexp pname.Clang_ast_t.ni_name 0 >= 0
with Not_found -> false
let location_from_sinfo info =
CLocation.get_sil_location_from_range info.Clang_ast_t.si_source_range true
let location_from_dinfo info =
CLocation.get_sil_location_from_range info.Clang_ast_t.di_source_range true
let proc_name_from_context context =
Cfg.Procdesc.get_proc_name (CContext.get_procdesc context)
(* === Warnings on properties === *) (* === Warnings on properties === *)
(* Strong Delegate Warning: a property with name delegate should not be declared strong *) (* Strong Delegate Warning: a property with name delegate should not be declared strong *)
let checker_strong_delegate_warning decl_info pname obj_c_property_decl_info = let strong_delegate_warning decl_info pname obj_c_property_decl_info =
Printing.log_out "Checking for STRONG_DELEGATE property warning\n"; let condition = property_name_contains_word pname "delegate"
let delegate_regexp = Str.regexp_string_case_fold "delegate" in
let pname_contains_delegate = try
Str.search_forward delegate_regexp pname.Clang_ast_t.ni_name 0 >= 0
with Not_found -> false in
let condition = pname_contains_delegate
&& ObjcProperty_decl.is_strong_property obj_c_property_decl_info in && ObjcProperty_decl.is_strong_property obj_c_property_decl_info in
let warning_desc = if condition then
{ name = "STRONG_DELEGATE_WARNING"; Some { name = "STRONG_DELEGATE_WARNING";
description = "Property or ivar "^pname.Clang_ast_t.ni_name^" declared strong"; description = "Property or ivar "^pname.Clang_ast_t.ni_name^" declared strong";
suggestion = "In general delegates should be declared weak or assign"; suggestion = "In general delegates should be declared weak or assign";
loc = CLocation.get_sil_location_from_range decl_info.Clang_ast_t.di_source_range true; loc = location_from_dinfo decl_info; }
} in else None
(condition, warning_desc)
(* Direct Atomic Property access: (* Direct Atomic Property access:
a property declared atomic should not be accessed directly via its ivar *) a property declared atomic should not be accessed directly via its ivar *)
let direct_atomic_property_access context stmt_info ivar_name = let direct_atomic_property_access_warning context stmt_info ivar_name =
let tenv = CContext.get_tenv context in let tenv = CContext.get_tenv context in
let mname = Cfg.Procdesc.get_proc_name (CContext.get_procdesc context) in let mname = proc_name_from_context context in
let ivar, cname = match ivar_name with let ivar, cname = match ivar_name with
| Some n -> | Some n ->
General_utils.mk_class_field_name n, General_utils.mk_class_field_name n,
Ast_utils.get_class_name_from_member n Ast_utils.get_class_name_from_member n
| _ -> Ident.create_fieldname (Mangled.from_string "") 0, "" in | _ -> Ident.create_fieldname (Mangled.from_string "") 0, "" in
let tname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string cname) in let tname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string cname) in
let loc = CLocation.get_sil_location_from_range stmt_info.Clang_ast_t.si_source_range true in let condition = match Sil.tenv_lookup tenv tname with
match Sil.tenv_lookup tenv tname with | Some Sil.Tstruct { Sil.instance_fields; static_fields } ->
| Some Sil.Tstruct { Sil.instance_fields; static_fields } -> (* We give the warning when:
(* We give the warning when: (1) the property has the atomic attribute and
(1) the property has the atomic attribute and (2) the access of the ivar is not in a getter or setter method.
(2) the access of the ivar is not in a getter or setter method. (3) the access of the ivar is not in the init method
(3) the access of the ivar is not in the init method Last two conditions avoids false positives *)
Last two conditions avoids false positives *) (CField_decl.is_ivar_atomic ivar (instance_fields @ static_fields))
let condition = (CField_decl.is_ivar_atomic ivar (instance_fields @ static_fields)) && not (CContext.is_curr_proc_objc_getter context ivar)
&& not (CContext.is_curr_proc_objc_getter context ivar) && not (CContext.is_curr_proc_objc_setter context ivar)
&& not (CContext.is_curr_proc_objc_setter context ivar) && not (Procname.is_constructor mname)
&& not (Procname.is_constructor mname) && not (Procname.is_objc_dealloc mname)
&& not (Procname.is_objc_dealloc mname) in | _ -> false in
let warning_desc = { if condition then
name = "DIRECT_ATOMIC_PROPERTY_ACCESS"; Some {
description = "Direct access to ivar " ^ (Ident.fieldname_to_string ivar) ^ name = "DIRECT_ATOMIC_PROPERTY_ACCESS";
" of an atomic property"; description = "Direct access to ivar " ^ (Ident.fieldname_to_string ivar) ^
suggestion = "Accessing an ivar of an atomic property makes the property nonatomic"; " of an atomic property";
loc = loc; suggestion = "Accessing an ivar of an atomic property makes the property nonatomic";
} in loc = location_from_sinfo stmt_info; }
(condition, Some warning_desc) else None
| _ -> (false, None) (* No warning *)
(* CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK: C++ references (* CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK: C++ references
should not be captured in blocks. *) should not be captured in blocks. *)
let captured_cxx_ref_in_objc_block stmt_info captured_vars = let captured_cxx_ref_in_objc_block_warning stmt_info captured_vars =
let is_cxx_ref (_, typ) = let is_cxx_ref (_, typ) =
match typ with match typ with
| Sil.Tptr(_, Sil.Pk_reference) -> true | Sil.Tptr(_, Sil.Pk_reference) -> true
| _ -> false in | _ -> false in
let capt_refs = IList.filter is_cxx_ref captured_vars in let capt_refs = IList.filter is_cxx_ref captured_vars in
match capt_refs with let pvar_descs =
| [] -> (false, None) (* No warning *) IList.fold_left (fun s (v, _) -> s ^ " '" ^ (Sil.pvar_to_string v) ^ "' ") "" capt_refs in
| _ -> (* Fire if the list of captured references is not empty *)
let pvar_descs = let condition = IList.length capt_refs > 0 in
IList.fold_left (fun s (v, _) -> s ^ " '" ^ (Sil.pvar_to_string v) ^ "' ") "" capt_refs in if condition then
let loc = CLocation.get_sil_location_from_range stmt_info.Clang_ast_t.si_source_range true in Some {
let warning_desc = { name = "CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK";
name = "CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK"; description = "C++ Reference variable(s) " ^ pvar_descs ^
description = "C++ Reference variable(s) " ^ pvar_descs ^ " captured by Objective-C block";
" captured by Objective-C block"; suggestion = "C++ References are unmanaged and may be invalid " ^
suggestion = "C++ References are unmanaged and may be invalid " ^ "by the time the block executes.";
"by the time the block executes."; loc = location_from_sinfo stmt_info; }
loc = loc; else None
} in
(true, Some warning_desc)

@ -7,20 +7,26 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*) *)
type warning_desc = {
name : string; (* name for the checker, this will be a kind of bug *)
description : string; (* Description in the error message *)
suggestion : string; (* an optional suggestion or correction *)
loc : Location.t; (* location in the code *)
}
(* === Warnings on properties === *) (* === Warnings on properties === *)
(* Strong Delegate Warning: a property with name delegate should not be declared strong *) (* Strong Delegate Warning: a property with name delegate should not be declared strong *)
val checker_strong_delegate_warning : Clang_ast_t.decl_info -> Clang_ast_t.named_decl_info -> val strong_delegate_warning : Clang_ast_t.decl_info -> Clang_ast_t.named_decl_info ->
Clang_ast_t.obj_c_property_decl_info -> (bool * CFrontend_utils.General_utils.warning_desc) Clang_ast_t.obj_c_property_decl_info -> warning_desc option
(* Direct Atomic Property access: (* Direct Atomic Property access:
a property declared atomic should not be accesses directly via its iva *) a property declared atomic should not be accesses directly via its iva *)
val direct_atomic_property_access : val direct_atomic_property_access_warning :
CContext.t -> Clang_ast_t.stmt_info -> Clang_ast_t.named_decl_info option -> CContext.t -> Clang_ast_t.stmt_info -> Clang_ast_t.named_decl_info option ->
(bool * CFrontend_utils.General_utils.warning_desc option) warning_desc option
(* CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK: C++ references (* CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK: C++ references
should not be captured in blocks. *) should not be captured in blocks. *)
val captured_cxx_ref_in_objc_block : Clang_ast_t.stmt_info -> (Sil.pvar * Sil.typ) list -> val captured_cxx_ref_in_objc_block_warning : Clang_ast_t.stmt_info -> (Sil.pvar * Sil.typ) list ->
(bool * CFrontend_utils.General_utils.warning_desc option) warning_desc option

@ -7,27 +7,32 @@
* of patent rights can be found in the PATENTS file in the same directory. * of patent rights can be found in the PATENTS file in the same directory.
*) *)
(* Module for warnings detected at translation time by the frontend
* To specify a checker define the following:
* - condition: a boolean condition when the warning should be flagged
* - description: a string describing the warning
* - loc: the location where is occurs
*)
open CFrontend_utils open CFrontend_utils
open General_utils
(* List of checkers on properties *) (* List of checkers on properties *)
let property_checkers_list = [CFrontend_checkers.checker_strong_delegate_warning] let property_checkers_list = [CFrontend_checkers.strong_delegate_warning]
(* Invocation of checker belonging to property_checker_list *)
let checkers_for_property decl_info pname_info pdi checker =
checker decl_info pname_info pdi
(* List of checkers on ivar access *) (* List of checkers on ivar access *)
let ivar_access_checker_list = [CFrontend_checkers.direct_atomic_property_access] let ivar_access_checker_list = [CFrontend_checkers.direct_atomic_property_access_warning]
(* Invocation of checker belonging to ivar_access_checker_list *)
let checkers_for_ivar context stmt_info dr_name checker =
checker context stmt_info dr_name
(* List of checkers for captured vars in objc blocks *) (* List of checkers for captured vars in objc blocks *)
let captured_vars_checker_list = [CFrontend_checkers.captured_cxx_ref_in_objc_block] let captured_vars_checker_list = [CFrontend_checkers.captured_cxx_ref_in_objc_block_warning]
(* Invocation of checker belonging to captured_vars_checker_list *)
let checkers_for_capture_vars stmt_info captured_vars checker =
checker stmt_info captured_vars
(* Add a frontend warning with a description desc at location loc to the errlog of a proc desc *) (* Add a frontend warning with a description desc at location loc to the errlog of a proc desc *)
let log_frontend_warning pdesc warn_desc = let log_frontend_warning pdesc warn_desc =
let open CFrontend_checkers in
let loc = warn_desc.loc in let loc = warn_desc.loc in
let errlog = Cfg.Procdesc.get_err_log pdesc in let errlog = Cfg.Procdesc.get_err_log pdesc in
let err_desc = let err_desc =
@ -36,16 +41,25 @@ let log_frontend_warning pdesc warn_desc =
(warn_desc.name, err_desc, __POS__) in (warn_desc.name, err_desc, __POS__) in
Reporting.log_error_from_errlog errlog exn ~loc:(Some loc) Reporting.log_error_from_errlog errlog exn ~loc:(Some loc)
(* General invocation function for checkers
Takes
1. f a particular way to apply a checker, it's a partial function
2. context
3. the list of checkers to be applied *)
let invoke_set_of_checkers f pdesc checkers =
IList.iter (fun checker ->
match f checker with
| Some warning_desc -> log_frontend_warning pdesc warning_desc
| None -> ()) checkers
(* Call all checkers on properties of class c *) (* Call all checkers on properties of class c *)
let rec check_for_property_errors cfg cg tenv class_name decl_list = let rec check_for_property_errors cfg cg tenv class_name decl_list =
let open Clang_ast_t in let open Clang_ast_t in
let do_one_property decl_info pname_info pdi = let do_one_property decl_info pname_info pdi =
IList.iter (fun checker -> let pdesc =
let (condition, warning_desc) = checker decl_info pname_info pdi in CMethod_trans.get_method_for_frontend_checks cfg cg tenv class_name decl_info in
if condition then let call_property_checker = checkers_for_property decl_info pname_info pdi in
let proc_desc = invoke_set_of_checkers call_property_checker pdesc property_checkers_list in
CMethod_trans.get_method_for_frontend_checks cfg cg tenv class_name decl_info in
log_frontend_warning proc_desc warning_desc) property_checkers_list in
match decl_list with match decl_list with
| [] -> () | [] -> ()
| ObjCPropertyDecl (decl_info, pname_info, pdi) :: rest -> | ObjCPropertyDecl (decl_info, pname_info, pdi) :: rest ->
@ -54,18 +68,40 @@ let rec check_for_property_errors cfg cg tenv class_name decl_list =
| _ :: rest -> | _ :: rest ->
check_for_property_errors cfg cg tenv class_name rest check_for_property_errors cfg cg tenv class_name rest
(* Call checkers on a specific access of an ivar *) let get_categories_decls decl_ref =
let check_for_ivar_errors context stmt_info obj_c_ivar_ref_expr_info = match Ast_utils.get_decl_opt_with_decl_ref decl_ref with
let dr_name = obj_c_ivar_ref_expr_info.Clang_ast_t.ovrei_decl_ref.Clang_ast_t.dr_name in | Some ObjCCategoryDecl (_, _, decls, _, _)
let pdesc = CContext.get_procdesc context in | Some ObjCInterfaceDecl (_, _, decls, _, _) -> decls
IList.iter (fun checker -> | _ -> []
match checker context stmt_info dr_name with
| true, Some warning_desc -> log_frontend_warning pdesc warning_desc
| _, _ -> ()) ivar_access_checker_list
let check_for_captured_vars context stmt_info captured_vars = let run_frontend_checkers_on_stmt trans_state instr =
let open Clang_ast_t in
let context = trans_state.CTrans_utils.context in
let pdesc = CContext.get_procdesc context in let pdesc = CContext.get_procdesc context in
IList.iter (fun checker -> match instr with
match checker stmt_info captured_vars with | ObjCIvarRefExpr(stmt_info, _, _, obj_c_ivar_ref_expr_info) ->
| true, Some warning_desc -> log_frontend_warning pdesc warning_desc let dr_name = obj_c_ivar_ref_expr_info.Clang_ast_t.ovrei_decl_ref.Clang_ast_t.dr_name in
| _, _ -> ()) captured_vars_checker_list let call_checker_for_ivar = checkers_for_ivar context stmt_info dr_name in
invoke_set_of_checkers call_checker_for_ivar pdesc ivar_access_checker_list
| BlockExpr(stmt_info, _ , _, Clang_ast_t.BlockDecl (_, block_decl_info)) ->
let captured_block_vars = block_decl_info.Clang_ast_t.bdi_captured_variables in
let captured_vars = CVar_decl.captured_vars_from_block_info context captured_block_vars in
let call_captured_vars_checker = checkers_for_capture_vars stmt_info captured_vars in
invoke_set_of_checkers call_captured_vars_checker pdesc captured_vars_checker_list
| _ -> ()
let run_frontend_checkers_on_decl tenv cg cfg dec =
let open Clang_ast_t in
match dec with
| ObjCCategoryImplDecl(_, name_info, decl_list, _, ocidi) ->
let name = Ast_utils.get_qualified_name name_info in
let curr_class = ObjcCategory_decl.get_curr_class_from_category_impl name ocidi in
let decls = (get_categories_decls ocidi.Clang_ast_t.ocidi_category_decl) @ decl_list in
let name = CContext.get_curr_class_name curr_class in
check_for_property_errors cfg cg tenv name decls
| ObjCImplementationDecl(_, _, decl_list, _, idi) ->
let curr_class = ObjcInterface_decl.get_curr_class_impl idi in
let name = CContext.get_curr_class_name curr_class in
let decls = (get_categories_decls idi.Clang_ast_t.oidi_class_interface) @ decl_list in
check_for_property_errors cfg cg tenv name decls
| _ -> ()

@ -10,14 +10,9 @@
(* Module for warnings detected at translation time by the frontend *) (* Module for warnings detected at translation time by the frontend *)
(* Run frontend checkers on a statement *)
val run_frontend_checkers_on_stmt : CTrans_utils.trans_state -> Clang_ast_t.stmt -> unit
(* Checks for warnings on properties of class c *) (* Run frontend checkers on a declaration *)
val check_for_property_errors : Cfg.cfg -> Cg.t -> Sil.tenv -> string -> Clang_ast_t.decl list -> val run_frontend_checkers_on_decl : Sil.tenv -> Cg.t -> Cfg.cfg -> Clang_ast_t.decl -> unit
unit
(* Call checkers on a specific access of an ivar *)
val check_for_ivar_errors :
CContext.t -> Clang_ast_t.stmt_info -> Clang_ast_t.obj_c_ivar_ref_expr_info -> unit
val check_for_captured_vars : CContext.t -> Clang_ast_t.stmt_info ->
(Sil.pvar * Sil.typ) list -> unit

@ -396,13 +396,6 @@ let get_fresh_block_index () =
module General_utils = module General_utils =
struct struct
type warning_desc = {
name : string;
description : string;
suggestion : string; (* an optional suggestion or correction *)
loc : Location.t;
}
type var_info = Clang_ast_t.decl_info * Clang_ast_t.type_ptr * Clang_ast_t.var_decl_info * bool type var_info = Clang_ast_t.decl_info * Clang_ast_t.type_ptr * Clang_ast_t.var_decl_info * bool
let rec swap_elements_list l = let rec swap_elements_list l =

@ -124,13 +124,6 @@ end
module General_utils : module General_utils :
sig sig
type warning_desc = {
name : string;
description : string;
suggestion : string; (* an optional suggestion or correction *)
loc : Location.t;
}
type var_info = Clang_ast_t.decl_info * Clang_ast_t.type_ptr * Clang_ast_t.var_decl_info * bool type var_info = Clang_ast_t.decl_info * Clang_ast_t.type_ptr * Clang_ast_t.var_decl_info * bool
val string_from_list : string list -> string val string_from_list : string list -> string

@ -1773,7 +1773,6 @@ struct
and objCIvarRefExpr_trans trans_state stmt_info stmt_list obj_c_ivar_ref_expr_info = and objCIvarRefExpr_trans trans_state stmt_info stmt_list obj_c_ivar_ref_expr_info =
let decl_ref = obj_c_ivar_ref_expr_info.Clang_ast_t.ovrei_decl_ref in let decl_ref = obj_c_ivar_ref_expr_info.Clang_ast_t.ovrei_decl_ref in
CFrontend_errors.check_for_ivar_errors trans_state.context stmt_info obj_c_ivar_ref_expr_info;
do_memb_ivar_ref_exp trans_state stmt_info stmt_list decl_ref do_memb_ivar_ref_exp trans_state stmt_info stmt_list decl_ref
and memberExpr_trans trans_state stmt_info stmt_list member_expr_info = and memberExpr_trans trans_state stmt_info stmt_list member_expr_info =
@ -1941,7 +1940,6 @@ struct
Cg.add_edge context.cg procname block_pname; Cg.add_edge context.cg procname block_pname;
let captured_block_vars = block_decl_info.Clang_ast_t.bdi_captured_variables in let captured_block_vars = block_decl_info.Clang_ast_t.bdi_captured_variables in
let captured_vars = CVar_decl.captured_vars_from_block_info context captured_block_vars in let captured_vars = CVar_decl.captured_vars_from_block_info context captured_block_vars in
CFrontend_errors.check_for_captured_vars context stmt_info captured_vars;
let ids_instrs = IList.map assign_captured_var captured_vars in let ids_instrs = IList.map assign_captured_var captured_vars in
let ids, instrs = IList.split ids_instrs in let ids, instrs = IList.split ids_instrs in
let block_data = (context, type_ptr, block_pname, captured_vars) in let block_data = (context, type_ptr, block_pname, captured_vars) in
@ -2054,6 +2052,8 @@ struct
(* a trans_state containing current info on the translation and it returns *) (* a trans_state containing current info on the translation and it returns *)
(* a result_state.*) (* a result_state.*)
and instruction trans_state instr = and instruction trans_state instr =
(* Run the frontend checkers on this instruction *)
CFrontend_errors.run_frontend_checkers_on_stmt trans_state instr;
let stmt_kind = Clang_ast_proj.get_stmt_kind_string instr in let stmt_kind = Clang_ast_proj.get_stmt_kind_string instr in
let stmt_info, _ = Clang_ast_proj.get_stmt_tuple instr in let stmt_info, _ = Clang_ast_proj.get_stmt_tuple instr in
let stmt_pointer = stmt_info.Clang_ast_t.si_pointer in let stmt_pointer = stmt_info.Clang_ast_t.si_pointer in

@ -1,32 +1,39 @@
digraph iCFG { digraph iCFG {
8 [label="8: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 29]\n *&s:class NSString *=n$4 [line 29]\n REMOVE_TEMPS(n$4); [line 29]\n " shape="box"] 10 [label="10: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 29]\n *&s:class NSString *=n$4 [line 29]\n REMOVE_TEMPS(n$4); [line 29]\n " shape="box"]
8 -> 7 ; 10 -> 9 ;
7 [label="7: Return Stmt \n n$3=*&s:class NSString * [line 30]\n *&return:class NSString *=n$3 [line 30]\n REMOVE_TEMPS(n$3); [line 30]\n NULLIFY(&s,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] 9 [label="9: Return Stmt \n n$3=*&s:class NSString * [line 30]\n *&return:class NSString *=n$3 [line 30]\n REMOVE_TEMPS(n$3); [line 30]\n NULLIFY(&s,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"]
7 -> 6 ; 9 -> 8 ;
6 [label="6: Exit A_newS \n " color=yellow style=filled] 8 [label="8: Exit A_newS \n " color=yellow style=filled]
5 [label="5: Start A_newS\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 28]\n NULLIFY(&s,false); [line 28]\n NULLIFY(&self,false); [line 28]\n " color=yellow style=filled] 7 [label="7: Start A_newS\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 28]\n NULLIFY(&s,false); [line 28]\n NULLIFY(&self,false); [line 28]\n " color=yellow style=filled]
5 -> 8 ; 7 -> 10 ;
4 [label="4: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 23]\n *&s:class NSString *=n$2 [line 23]\n REMOVE_TEMPS(n$2); [line 23]\n " shape="box"] 6 [label="6: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 23]\n *&s:class NSString *=n$2 [line 23]\n REMOVE_TEMPS(n$2); [line 23]\n " shape="box"]
4 -> 3 ; 6 -> 5 ;
3 [label="3: Return Stmt \n n$0=*&s:class NSString * [line 24]\n *&return:class NSString *=n$0 [line 24]\n n$1=_fun___set_autorelease_attribute(n$0:class NSString *) [line 24]\n REMOVE_TEMPS(n$0,n$1); [line 24]\n NULLIFY(&s,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"] 5 [label="5: Return Stmt \n n$0=*&s:class NSString * [line 24]\n *&return:class NSString *=n$0 [line 24]\n n$1=_fun___set_autorelease_attribute(n$0:class NSString *) [line 24]\n REMOVE_TEMPS(n$0,n$1); [line 24]\n NULLIFY(&s,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"]
3 -> 2 ; 5 -> 4 ;
2 [label="2: Exit A_getS \n " color=yellow style=filled] 4 [label="4: Exit A_getS \n " color=yellow style=filled]
1 [label="1: Start A_getS\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n NULLIFY(&s,false); [line 22]\n NULLIFY(&self,false); [line 22]\n " color=yellow style=filled] 3 [label="3: Start A_getS\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n NULLIFY(&s,false); [line 22]\n NULLIFY(&self,false); [line 22]\n " color=yellow style=filled]
1 -> 4 ; 3 -> 6 ;
2 [label="2: Exit A_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start A_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 2 ;
} }

@ -1,137 +1,144 @@
digraph iCFG { digraph iCFG {
35 [label="35: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class NSAutoreleasePool ):unsigned long ) [line 60]\n n$5=_fun_NSObject_init(n$4:class NSAutoreleasePool *) virtual [line 60]\n *&pool:class NSAutoreleasePool *=n$5 [line 60]\n REMOVE_TEMPS(n$4,n$5); [line 60]\n " shape="box"] 37 [label="37: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class NSAutoreleasePool ):unsigned long ) [line 60]\n n$5=_fun_NSObject_init(n$4:class NSAutoreleasePool *) virtual [line 60]\n *&pool:class NSAutoreleasePool *=n$5 [line 60]\n REMOVE_TEMPS(n$4,n$5); [line 60]\n " shape="box"]
37 -> 36 ;
36 [label="36: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 61]\n n$3=_fun___set_autorelease_attribute(n$2:class NSString *) [line 61]\n *&string:class NSString *=n$3 [line 61]\n REMOVE_TEMPS(n$2,n$3); [line 61]\n " shape="box"]
36 -> 35 ;
35 [label="35: Message Call: release \n n$1=*&pool:class NSAutoreleasePool * [line 63]\n _fun___objc_release_autorelease_pool(n$1:class NSAutoreleasePool *) [line 63]\n REMOVE_TEMPS(n$1); [line 63]\n NULLIFY(&pool,false); [line 63]\n " shape="box"]
35 -> 34 ; 35 -> 34 ;
34 [label="34: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 61]\n n$3=_fun___set_autorelease_attribute(n$2:class NSString *) [line 61]\n *&string:class NSString *=n$3 [line 61]\n REMOVE_TEMPS(n$2,n$3); [line 61]\n " shape="box"] 34 [label="34: DeclStmt \n n$0=*&string:class NSString * [line 64]\n *&c:class NSString *=n$0 [line 64]\n REMOVE_TEMPS(n$0); [line 64]\n NULLIFY(&c,false); [line 64]\n NULLIFY(&string,false); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"]
34 -> 33 ; 34 -> 33 ;
33 [label="33: Message Call: release \n n$1=*&pool:class NSAutoreleasePool * [line 63]\n _fun___objc_release_autorelease_pool(n$1:class NSAutoreleasePool *) [line 63]\n REMOVE_TEMPS(n$1); [line 63]\n NULLIFY(&pool,false); [line 63]\n " shape="box"] 33 [label="33: Exit test3 \n " color=yellow style=filled]
33 -> 32 ; 32 [label="32: Start test3\nFormals: \nLocals: c:class NSString * string:class NSString * pool:class NSAutoreleasePool * \n DECLARE_LOCALS(&return,&c,&string,&pool); [line 59]\n NULLIFY(&c,false); [line 59]\n NULLIFY(&pool,false); [line 59]\n NULLIFY(&string,false); [line 59]\n " color=yellow style=filled]
32 [label="32: DeclStmt \n n$0=*&string:class NSString * [line 64]\n *&c:class NSString *=n$0 [line 64]\n REMOVE_TEMPS(n$0); [line 64]\n NULLIFY(&c,false); [line 64]\n NULLIFY(&string,false); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"]
32 -> 31 ; 32 -> 37 ;
31 [label="31: Exit test3 \n " color=yellow style=filled] 31 [label="31: DeclStmt \n *&s1:class A *=0 [line 48]\n " shape="box"]
30 [label="30: Start test3\nFormals: \nLocals: c:class NSString * string:class NSString * pool:class NSAutoreleasePool * \n DECLARE_LOCALS(&return,&c,&string,&pool); [line 59]\n NULLIFY(&c,false); [line 59]\n NULLIFY(&pool,false); [line 59]\n NULLIFY(&string,false); [line 59]\n " color=yellow style=filled] 31 -> 30 ;
30 [label="30: DeclStmt \n *&s2:class A *=0 [line 49]\n " shape="box"]
30 -> 35 ; 30 -> 29 ;
29 [label="29: DeclStmt \n *&s1:class A *=0 [line 48]\n " shape="box"] 29 [label="29: DeclStmt \n *&s3:class A *=0 [line 50]\n " shape="box"]
29 -> 28 ; 29 -> 28 ;
28 [label="28: DeclStmt \n *&s2:class A *=0 [line 49]\n " shape="box"] 28 [label="28: BinaryOperatorStmt: Assign \n n$3=_fun_createA() [line 52]\n *&s1:class A *=n$3 [line 52]\n REMOVE_TEMPS(n$3); [line 52]\n " shape="box"]
28 -> 27 ; 28 -> 27 ;
27 [label="27: DeclStmt \n *&s3:class A *=0 [line 50]\n " shape="box"] 27 [label="27: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 53]\n *&s2:class A *=n$2 [line 53]\n REMOVE_TEMPS(n$2); [line 53]\n " shape="box"]
27 -> 26 ; 27 -> 26 ;
26 [label="26: BinaryOperatorStmt: Assign \n n$3=_fun_createA() [line 52]\n *&s1:class A *=n$3 [line 52]\n REMOVE_TEMPS(n$3); [line 52]\n " shape="box"] 26 [label="26: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 54]\n *&s3:class A *=n$1 [line 54]\n REMOVE_TEMPS(n$1); [line 54]\n " shape="box"]
26 -> 25 ; 26 -> 25 ;
25 [label="25: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 53]\n *&s2:class A *=n$2 [line 53]\n REMOVE_TEMPS(n$2); [line 53]\n " shape="box"] 25 [label="25: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class A *,&s3:class A *,&s2:class A *) [line 51]\n REMOVE_TEMPS(n$0); [line 51]\n " shape="box"]
25 -> 24 ; 25 -> 24 ;
24 [label="24: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 54]\n *&s3:class A *=n$1 [line 54]\n REMOVE_TEMPS(n$1); [line 54]\n " shape="box"] 24 [label="24: Return Stmt \n *&return:int =0 [line 56]\n NULLIFY(&s1,false); [line 56]\n NULLIFY(&s2,false); [line 56]\n NULLIFY(&s3,false); [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"]
24 -> 23 ; 24 -> 23 ;
23 [label="23: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class A *,&s3:class A *,&s2:class A *) [line 51]\n REMOVE_TEMPS(n$0); [line 51]\n " shape="box"] 23 [label="23: Exit test2 \n " color=yellow style=filled]
23 -> 22 ; 22 [label="22: Start test2\nFormals: \nLocals: s3:class A * s2:class A * s1:class A * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 47]\n " color=yellow style=filled]
22 [label="22: Return Stmt \n *&return:int =0 [line 56]\n NULLIFY(&s1,false); [line 56]\n NULLIFY(&s2,false); [line 56]\n NULLIFY(&s3,false); [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"]
22 -> 21 ; 22 -> 31 ;
21 [label="21: Exit test2 \n " color=yellow style=filled] 21 [label="21: DeclStmt \n *&s1:class A *=0 [line 35]\n " shape="box"]
20 [label="20: Start test2\nFormals: \nLocals: s3:class A * s2:class A * s1:class A * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 47]\n " color=yellow style=filled] 21 -> 20 ;
20 [label="20: DeclStmt \n *&s2:class A *=0 [line 36]\n " shape="box"]
20 -> 29 ; 20 -> 19 ;
19 [label="19: DeclStmt \n *&s1:class A *=0 [line 35]\n " shape="box"] 19 [label="19: DeclStmt \n *&s3:class A *=0 [line 37]\n " shape="box"]
19 -> 18 ; 19 -> 18 ;
18 [label="18: DeclStmt \n *&s2:class A *=0 [line 36]\n " shape="box"] 18 [label="18: BinaryOperatorStmt: Assign \n n$5=_fun_createA() [line 39]\n *&s1:class A *=n$5 [line 39]\n REMOVE_TEMPS(n$5); [line 39]\n " shape="box"]
18 -> 17 ; 18 -> 17 ;
17 [label="17: DeclStmt \n *&s3:class A *=0 [line 37]\n " shape="box"] 17 [label="17: Message Call: retain \n n$3=*&s1:class A * [line 40]\n n$4=_fun___objc_retain(n$3:class A *) [line 40]\n REMOVE_TEMPS(n$3,n$4); [line 40]\n " shape="box"]
17 -> 16 ; 17 -> 16 ;
16 [label="16: BinaryOperatorStmt: Assign \n n$5=_fun_createA() [line 39]\n *&s1:class A *=n$5 [line 39]\n REMOVE_TEMPS(n$5); [line 39]\n " shape="box"] 16 [label="16: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 41]\n *&s2:class A *=n$2 [line 41]\n REMOVE_TEMPS(n$2); [line 41]\n " shape="box"]
16 -> 15 ; 16 -> 15 ;
15 [label="15: Message Call: retain \n n$3=*&s1:class A * [line 40]\n n$4=_fun___objc_retain(n$3:class A *) [line 40]\n REMOVE_TEMPS(n$3,n$4); [line 40]\n " shape="box"] 15 [label="15: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 42]\n *&s3:class A *=n$1 [line 42]\n REMOVE_TEMPS(n$1); [line 42]\n " shape="box"]
15 -> 14 ; 15 -> 14 ;
14 [label="14: BinaryOperatorStmt: Assign \n n$2=_fun_createA() [line 41]\n *&s2:class A *=n$2 [line 41]\n REMOVE_TEMPS(n$2); [line 41]\n " shape="box"] 14 [label="14: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class A *,&s2:class A *,&s3:class A *) [line 38]\n REMOVE_TEMPS(n$0); [line 38]\n " shape="box"]
14 -> 13 ; 14 -> 13 ;
13 [label="13: BinaryOperatorStmt: Assign \n n$1=_fun_createA() [line 42]\n *&s3:class A *=n$1 [line 42]\n REMOVE_TEMPS(n$1); [line 42]\n " shape="box"] 13 [label="13: Return Stmt \n *&return:int =0 [line 44]\n NULLIFY(&s1,false); [line 44]\n NULLIFY(&s2,false); [line 44]\n NULLIFY(&s3,false); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"]
13 -> 12 ; 13 -> 12 ;
12 [label="12: Release the autorelease pool \n n$0=_fun___objc_release_autorelease_pool(&s1:class A *,&s2:class A *,&s3:class A *) [line 38]\n REMOVE_TEMPS(n$0); [line 38]\n " shape="box"] 12 [label="12: Exit test1 \n " color=yellow style=filled]
12 -> 11 ; 11 [label="11: Start test1\nFormals: \nLocals: s3:class A * s2:class A * s1:class A * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 34]\n " color=yellow style=filled]
11 [label="11: Return Stmt \n *&return:int =0 [line 44]\n NULLIFY(&s1,false); [line 44]\n NULLIFY(&s2,false); [line 44]\n NULLIFY(&s3,false); [line 44]\n APPLY_ABSTRACTION; [line 44]\n " shape="box"]
11 -> 10 ; 11 -> 21 ;
10 [label="10: Exit test1 \n " color=yellow style=filled] 10 [label="10: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 30]\n n$3=_fun_NSObject_init(n$2:class A *) virtual [line 30]\n *&s1:class A *=n$3 [line 30]\n REMOVE_TEMPS(n$2,n$3); [line 30]\n " shape="box"]
9 [label="9: Start test1\nFormals: \nLocals: s3:class A * s2:class A * s1:class A * \n DECLARE_LOCALS(&return,&s3,&s2,&s1); [line 34]\n " color=yellow style=filled] 10 -> 9 ;
9 [label="9: Return Stmt \n n$0=*&s1:class A * [line 31]\n n$1=_fun___set_autorelease_attribute(n$0:class A *) [line 31]\n *&return:class A *=n$1 [line 31]\n REMOVE_TEMPS(n$0,n$1); [line 31]\n NULLIFY(&s1,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"]
9 -> 19 ; 9 -> 8 ;
8 [label="8: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 30]\n n$3=_fun_NSObject_init(n$2:class A *) virtual [line 30]\n *&s1:class A *=n$3 [line 30]\n REMOVE_TEMPS(n$2,n$3); [line 30]\n " shape="box"] 8 [label="8: Exit createA \n " color=yellow style=filled]
8 -> 7 ; 7 [label="7: Start createA\nFormals: \nLocals: s1:class A * \n DECLARE_LOCALS(&return,&s1); [line 29]\n NULLIFY(&s1,false); [line 29]\n " color=yellow style=filled]
7 [label="7: Return Stmt \n n$0=*&s1:class A * [line 31]\n n$1=_fun___set_autorelease_attribute(n$0:class A *) [line 31]\n *&return:class A *=n$1 [line 31]\n REMOVE_TEMPS(n$0,n$1); [line 31]\n NULLIFY(&s1,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"]
7 -> 6 ; 7 -> 10 ;
6 [label="6: Exit createA \n " color=yellow style=filled] 6 [label="6: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 23]\n *&s:class NSString *=n$2 [line 23]\n REMOVE_TEMPS(n$2); [line 23]\n " shape="box"]
5 [label="5: Start createA\nFormals: \nLocals: s1:class A * \n DECLARE_LOCALS(&return,&s1); [line 29]\n NULLIFY(&s1,false); [line 29]\n " color=yellow style=filled] 6 -> 5 ;
5 [label="5: Return Stmt \n n$0=*&s:class NSString * [line 24]\n n$1=_fun___set_autorelease_attribute(n$0:class NSString *) [line 24]\n *&return:class NSString *=n$1 [line 24]\n REMOVE_TEMPS(n$0,n$1); [line 24]\n NULLIFY(&s,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"]
5 -> 8 ; 5 -> 4 ;
4 [label="4: DeclStmt \n n$2=_fun___objc_alloc_no_fail(sizeof(class NSString ):unsigned long ) [line 23]\n *&s:class NSString *=n$2 [line 23]\n REMOVE_TEMPS(n$2); [line 23]\n " shape="box"] 4 [label="4: Exit A_main \n " color=yellow style=filled]
4 -> 3 ; 3 [label="3: Start A_main\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n NULLIFY(&s,false); [line 22]\n NULLIFY(&self,false); [line 22]\n " color=yellow style=filled]
3 [label="3: Return Stmt \n n$0=*&s:class NSString * [line 24]\n n$1=_fun___set_autorelease_attribute(n$0:class NSString *) [line 24]\n *&return:class NSString *=n$1 [line 24]\n REMOVE_TEMPS(n$0,n$1); [line 24]\n NULLIFY(&s,false); [line 24]\n APPLY_ABSTRACTION; [line 24]\n " shape="box"]
3 -> 2 ; 3 -> 6 ;
2 [label="2: Exit A_main \n " color=yellow style=filled] 2 [label="2: Exit A_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start A_main\nFormals: self:class A *\nLocals: s:class NSString * \n DECLARE_LOCALS(&return,&s); [line 22]\n NULLIFY(&s,false); [line 22]\n NULLIFY(&self,false); [line 22]\n " color=yellow style=filled] 1 [label="1: Start A_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 4 ; 1 -> 2 ;
} }

@ -1,182 +1,189 @@
digraph iCFG { digraph iCFG {
48 [label="48: DeclStmt \n n$35=_fun_FBColorCreateWithGray(0.000000:double ,0.300000:double ) [line 86]\n *&borderColor:struct CGColor *=n$35 [line 86]\n REMOVE_TEMPS(n$35); [line 86]\n " shape="box"] 50 [label="50: DeclStmt \n n$35=_fun_FBColorCreateWithGray(0.000000:double ,0.300000:double ) [line 86]\n *&borderColor:struct CGColor *=n$35 [line 86]\n REMOVE_TEMPS(n$35); [line 86]\n " shape="box"]
48 -> 47 ; 50 -> 49 ;
47 [label="47: Call _fun_CGColorRelease \n n$34=*&borderColor:struct CGColor * [line 87]\n _fun_CGColorRelease(n$34:struct CGColor *) [line 87]\n REMOVE_TEMPS(n$34); [line 87]\n NULLIFY(&borderColor,false); [line 87]\n APPLY_ABSTRACTION; [line 87]\n " shape="box"] 49 [label="49: Call _fun_CGColorRelease \n n$34=*&borderColor:struct CGColor * [line 87]\n _fun_CGColorRelease(n$34:struct CGColor *) [line 87]\n REMOVE_TEMPS(n$34); [line 87]\n NULLIFY(&borderColor,false); [line 87]\n APPLY_ABSTRACTION; [line 87]\n " shape="box"]
47 -> 46 ; 49 -> 48 ;
46 [label="46: Exit MemoryLeakExample_testFBColorCreateWithGray \n " color=yellow style=filled] 48 [label="48: Exit MemoryLeakExample_testFBColorCreateWithGray \n " color=yellow style=filled]
45 [label="45: Start MemoryLeakExample_testFBColorCreateWithGray\nFormals: self:class MemoryLeakExample *\nLocals: borderColor:struct CGColor * \n DECLARE_LOCALS(&return,&borderColor); [line 85]\n NULLIFY(&borderColor,false); [line 85]\n NULLIFY(&self,false); [line 85]\n " color=yellow style=filled] 47 [label="47: Start MemoryLeakExample_testFBColorCreateWithGray\nFormals: self:class MemoryLeakExample *\nLocals: borderColor:struct CGColor * \n DECLARE_LOCALS(&return,&borderColor); [line 85]\n NULLIFY(&borderColor,false); [line 85]\n NULLIFY(&self,false); [line 85]\n " color=yellow style=filled]
45 -> 48 ; 47 -> 50 ;
44 [label="44: DeclStmt \n n$33=_fun_CGBitmapContextCreateImage(0:struct CGContext *) [line 79]\n *&newImage:struct CGImage *=n$33 [line 79]\n REMOVE_TEMPS(n$33); [line 79]\n " shape="box"] 46 [label="46: DeclStmt \n n$33=_fun_CGBitmapContextCreateImage(0:struct CGContext *) [line 79]\n *&newImage:struct CGImage *=n$33 [line 79]\n REMOVE_TEMPS(n$33); [line 79]\n " shape="box"]
44 -> 43 ; 46 -> 45 ;
43 [label="43: Call _fun_CGImageRelease \n n$32=*&newImage:struct CGImage * [line 80]\n _fun_CGImageRelease(n$32:struct CGImage *) [line 80]\n REMOVE_TEMPS(n$32); [line 80]\n NULLIFY(&newImage,false); [line 80]\n APPLY_ABSTRACTION; [line 80]\n " shape="box"] 45 [label="45: Call _fun_CGImageRelease \n n$32=*&newImage:struct CGImage * [line 80]\n _fun_CGImageRelease(n$32:struct CGImage *) [line 80]\n REMOVE_TEMPS(n$32); [line 80]\n NULLIFY(&newImage,false); [line 80]\n APPLY_ABSTRACTION; [line 80]\n " shape="box"]
43 -> 42 ; 45 -> 44 ;
42 [label="42: Exit MemoryLeakExample_testImageRefRelease \n " color=yellow style=filled] 44 [label="44: Exit MemoryLeakExample_testImageRefRelease \n " color=yellow style=filled]
41 [label="41: Start MemoryLeakExample_testImageRefRelease\nFormals: \nLocals: newImage:struct CGImage * \n DECLARE_LOCALS(&return,&newImage); [line 78]\n NULLIFY(&newImage,false); [line 78]\n " color=yellow style=filled] 43 [label="43: Start MemoryLeakExample_testImageRefRelease\nFormals: \nLocals: newImage:struct CGImage * \n DECLARE_LOCALS(&return,&newImage); [line 78]\n NULLIFY(&newImage,false); [line 78]\n " color=yellow style=filled]
41 -> 44 ; 43 -> 46 ;
40 [label="40: DeclStmt \n n$31=_fun_SecTrustCopyPublicKey(0:struct __SecTrust *) [line 74]\n *&allowedPublicKey:struct __SecKey *=n$31 [line 74]\n REMOVE_TEMPS(n$31); [line 74]\n " shape="box"] 42 [label="42: DeclStmt \n n$31=_fun_SecTrustCopyPublicKey(0:struct __SecTrust *) [line 74]\n *&allowedPublicKey:struct __SecKey *=n$31 [line 74]\n REMOVE_TEMPS(n$31); [line 74]\n " shape="box"]
40 -> 39 ; 42 -> 41 ;
39 [label="39: Call _fun___objc_release_cf \n n$30=*&allowedPublicKey:struct __SecKey * [line 75]\n _fun___objc_release_cf(1:_Bool ,n$30:void *) [line 75]\n REMOVE_TEMPS(n$30); [line 75]\n NULLIFY(&allowedPublicKey,false); [line 75]\n APPLY_ABSTRACTION; [line 75]\n " shape="box"] 41 [label="41: Call _fun___objc_release_cf \n n$30=*&allowedPublicKey:struct __SecKey * [line 75]\n _fun___objc_release_cf(1:_Bool ,n$30:void *) [line 75]\n REMOVE_TEMPS(n$30); [line 75]\n NULLIFY(&allowedPublicKey,false); [line 75]\n APPLY_ABSTRACTION; [line 75]\n " shape="box"]
39 -> 38 ; 41 -> 40 ;
38 [label="38: Exit MemoryLeakExample_test2NoLeak \n " color=yellow style=filled] 40 [label="40: Exit MemoryLeakExample_test2NoLeak \n " color=yellow style=filled]
37 [label="37: Start MemoryLeakExample_test2NoLeak\nFormals: \nLocals: allowedPublicKey:struct __SecKey * \n DECLARE_LOCALS(&return,&allowedPublicKey); [line 73]\n NULLIFY(&allowedPublicKey,false); [line 73]\n " color=yellow style=filled] 39 [label="39: Start MemoryLeakExample_test2NoLeak\nFormals: \nLocals: allowedPublicKey:struct __SecKey * \n DECLARE_LOCALS(&return,&allowedPublicKey); [line 73]\n NULLIFY(&allowedPublicKey,false); [line 73]\n " color=yellow style=filled]
37 -> 40 ; 39 -> 42 ;
36 [label="36: DeclStmt \n n$28=*&trust:struct __SecTrust * [line 70]\n n$29=_fun_SecTrustCopyPublicKey(n$28:struct __SecTrust *) [line 70]\n *&allowedPublicKey:struct __SecKey *=n$29 [line 70]\n REMOVE_TEMPS(n$28,n$29); [line 70]\n NULLIFY(&allowedPublicKey,false); [line 70]\n NULLIFY(&trust,false); [line 70]\n APPLY_ABSTRACTION; [line 70]\n " shape="box"] 38 [label="38: DeclStmt \n n$28=*&trust:struct __SecTrust * [line 70]\n n$29=_fun_SecTrustCopyPublicKey(n$28:struct __SecTrust *) [line 70]\n *&allowedPublicKey:struct __SecKey *=n$29 [line 70]\n REMOVE_TEMPS(n$28,n$29); [line 70]\n NULLIFY(&allowedPublicKey,false); [line 70]\n NULLIFY(&trust,false); [line 70]\n APPLY_ABSTRACTION; [line 70]\n " shape="box"]
36 -> 35 ; 38 -> 37 ;
35 [label="35: Exit MemoryLeakExample_test2: \n " color=yellow style=filled] 37 [label="37: Exit MemoryLeakExample_test2: \n " color=yellow style=filled]
34 [label="34: Start MemoryLeakExample_test2:\nFormals: trust:struct __SecTrust *\nLocals: allowedPublicKey:struct __SecKey * \n DECLARE_LOCALS(&return,&allowedPublicKey); [line 69]\n NULLIFY(&allowedPublicKey,false); [line 69]\n " color=yellow style=filled] 36 [label="36: Start MemoryLeakExample_test2:\nFormals: trust:struct __SecTrust *\nLocals: allowedPublicKey:struct __SecKey * \n DECLARE_LOCALS(&return,&allowedPublicKey); [line 69]\n NULLIFY(&allowedPublicKey,false); [line 69]\n " color=yellow style=filled]
34 -> 36 ; 36 -> 38 ;
33 [label="33: DeclStmt \n n$26=*&rect:struct CGRect [line 62]\n n$27=_fun_CGRectGetHeight(n$26:struct CGRect ) [line 62]\n *&lineThickness:double =(0.200000 * n$27) [line 62]\n REMOVE_TEMPS(n$26,n$27); [line 62]\n NULLIFY(&rect,false); [line 62]\n NULLIFY(&lineThickness,false); [line 62]\n " shape="box"] 35 [label="35: DeclStmt \n n$26=*&rect:struct CGRect [line 62]\n n$27=_fun_CGRectGetHeight(n$26:struct CGRect ) [line 62]\n *&lineThickness:double =(0.200000 * n$27) [line 62]\n REMOVE_TEMPS(n$26,n$27); [line 62]\n NULLIFY(&rect,false); [line 62]\n NULLIFY(&lineThickness,false); [line 62]\n " shape="box"]
35 -> 34 ;
34 [label="34: DeclStmt \n n$25=_fun_CGPathCreateMutable() [line 65]\n *&path1:struct CGPath *=n$25 [line 65]\n REMOVE_TEMPS(n$25); [line 65]\n " shape="box"]
34 -> 33 ;
33 [label="33: Call _fun___objc_release_cf \n n$24=*&path1:struct CGPath * [line 66]\n _fun___objc_release_cf(1:_Bool ,n$24:void *) [line 66]\n REMOVE_TEMPS(n$24); [line 66]\n NULLIFY(&path1,false); [line 66]\n APPLY_ABSTRACTION; [line 66]\n " shape="box"]
33 -> 32 ; 33 -> 32 ;
32 [label="32: DeclStmt \n n$25=_fun_CGPathCreateMutable() [line 65]\n *&path1:struct CGPath *=n$25 [line 65]\n REMOVE_TEMPS(n$25); [line 65]\n " shape="box"] 32 [label="32: Exit MemoryLeakExample_createCloseCrossGlyphNoLeak: \n " color=yellow style=filled]
32 -> 31 ; 31 [label="31: Start MemoryLeakExample_createCloseCrossGlyphNoLeak:\nFormals: rect:struct CGRect \nLocals: path1:struct CGPath * lineThickness:double \n DECLARE_LOCALS(&return,&path1,&lineThickness); [line 61]\n NULLIFY(&lineThickness,false); [line 61]\n NULLIFY(&path1,false); [line 61]\n " color=yellow style=filled]
31 [label="31: Call _fun___objc_release_cf \n n$24=*&path1:struct CGPath * [line 66]\n _fun___objc_release_cf(1:_Bool ,n$24:void *) [line 66]\n REMOVE_TEMPS(n$24); [line 66]\n NULLIFY(&path1,false); [line 66]\n APPLY_ABSTRACTION; [line 66]\n " shape="box"]
31 -> 30 ; 31 -> 35 ;
30 [label="30: Exit MemoryLeakExample_createCloseCrossGlyphNoLeak: \n " color=yellow style=filled] 30 [label="30: DeclStmt \n n$22=*&rect:struct CGRect [line 55]\n n$23=_fun_CGRectGetHeight(n$22:struct CGRect ) [line 55]\n *&lineThickness:double =(0.200000 * n$23) [line 55]\n REMOVE_TEMPS(n$22,n$23); [line 55]\n NULLIFY(&rect,false); [line 55]\n NULLIFY(&lineThickness,false); [line 55]\n " shape="box"]
29 [label="29: Start MemoryLeakExample_createCloseCrossGlyphNoLeak:\nFormals: rect:struct CGRect \nLocals: path1:struct CGPath * lineThickness:double \n DECLARE_LOCALS(&return,&path1,&lineThickness); [line 61]\n NULLIFY(&lineThickness,false); [line 61]\n NULLIFY(&path1,false); [line 61]\n " color=yellow style=filled] 30 -> 29 ;
29 [label="29: DeclStmt \n n$21=_fun_CGPathCreateMutable() [line 58]\n *&path1:struct CGPath *=n$21 [line 58]\n REMOVE_TEMPS(n$21); [line 58]\n NULLIFY(&path1,false); [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"]
29 -> 33 ; 29 -> 28 ;
28 [label="28: DeclStmt \n n$22=*&rect:struct CGRect [line 55]\n n$23=_fun_CGRectGetHeight(n$22:struct CGRect ) [line 55]\n *&lineThickness:double =(0.200000 * n$23) [line 55]\n REMOVE_TEMPS(n$22,n$23); [line 55]\n NULLIFY(&rect,false); [line 55]\n NULLIFY(&lineThickness,false); [line 55]\n " shape="box"] 28 [label="28: Exit MemoryLeakExample_createCloseCrossGlyph: \n " color=yellow style=filled]
28 -> 27 ; 27 [label="27: Start MemoryLeakExample_createCloseCrossGlyph:\nFormals: rect:struct CGRect \nLocals: path1:struct CGPath * lineThickness:double \n DECLARE_LOCALS(&return,&path1,&lineThickness); [line 54]\n NULLIFY(&lineThickness,false); [line 54]\n NULLIFY(&path1,false); [line 54]\n " color=yellow style=filled]
27 [label="27: DeclStmt \n n$21=_fun_CGPathCreateMutable() [line 58]\n *&path1:struct CGPath *=n$21 [line 58]\n REMOVE_TEMPS(n$21); [line 58]\n NULLIFY(&path1,false); [line 58]\n APPLY_ABSTRACTION; [line 58]\n " shape="box"]
27 -> 26 ; 27 -> 30 ;
26 [label="26: Exit MemoryLeakExample_createCloseCrossGlyph: \n " color=yellow style=filled] 26 [label="26: DeclStmt \n n$20=_fun_CTFramesetterCreateWithAttributedString(0:struct __CFAttributedString *) [line 50]\n *&framesetter:struct __CTFramesetter *=n$20 [line 50]\n REMOVE_TEMPS(n$20); [line 50]\n " shape="box"]
25 [label="25: Start MemoryLeakExample_createCloseCrossGlyph:\nFormals: rect:struct CGRect \nLocals: path1:struct CGPath * lineThickness:double \n DECLARE_LOCALS(&return,&path1,&lineThickness); [line 54]\n NULLIFY(&lineThickness,false); [line 54]\n NULLIFY(&path1,false); [line 54]\n " color=yellow style=filled] 26 -> 25 ;
25 [label="25: Call _fun___objc_release_cf \n n$19=*&framesetter:struct __CTFramesetter * [line 51]\n _fun___objc_release_cf(1:_Bool ,n$19:void *) [line 51]\n REMOVE_TEMPS(n$19); [line 51]\n NULLIFY(&framesetter,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"]
25 -> 28 ; 25 -> 24 ;
24 [label="24: DeclStmt \n n$20=_fun_CTFramesetterCreateWithAttributedString(0:struct __CFAttributedString *) [line 50]\n *&framesetter:struct __CTFramesetter *=n$20 [line 50]\n REMOVE_TEMPS(n$20); [line 50]\n " shape="box"] 24 [label="24: Exit MemoryLeakExample_test1NoLeak \n " color=yellow style=filled]
24 -> 23 ; 23 [label="23: Start MemoryLeakExample_test1NoLeak\nFormals: \nLocals: framesetter:struct __CTFramesetter * \n DECLARE_LOCALS(&return,&framesetter); [line 49]\n NULLIFY(&framesetter,false); [line 49]\n " color=yellow style=filled]
23 [label="23: Call _fun___objc_release_cf \n n$19=*&framesetter:struct __CTFramesetter * [line 51]\n _fun___objc_release_cf(1:_Bool ,n$19:void *) [line 51]\n REMOVE_TEMPS(n$19); [line 51]\n NULLIFY(&framesetter,false); [line 51]\n APPLY_ABSTRACTION; [line 51]\n " shape="box"]
23 -> 22 ; 23 -> 26 ;
22 [label="22: Exit MemoryLeakExample_test1NoLeak \n " color=yellow style=filled] 22 [label="22: DeclStmt \n n$17=*&str:struct __CFAttributedString * [line 46]\n n$18=_fun_CTFramesetterCreateWithAttributedString(n$17:struct __CFAttributedString *) [line 46]\n *&framesetter:struct __CTFramesetter *=n$18 [line 46]\n REMOVE_TEMPS(n$17,n$18); [line 46]\n NULLIFY(&framesetter,false); [line 46]\n NULLIFY(&str,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"]
21 [label="21: Start MemoryLeakExample_test1NoLeak\nFormals: \nLocals: framesetter:struct __CTFramesetter * \n DECLARE_LOCALS(&return,&framesetter); [line 49]\n NULLIFY(&framesetter,false); [line 49]\n " color=yellow style=filled] 22 -> 21 ;
21 [label="21: Exit MemoryLeakExample_test1: \n " color=yellow style=filled]
21 -> 24 ; 20 [label="20: Start MemoryLeakExample_test1:\nFormals: str:struct __CFAttributedString *\nLocals: framesetter:struct __CTFramesetter * \n DECLARE_LOCALS(&return,&framesetter); [line 45]\n NULLIFY(&framesetter,false); [line 45]\n " color=yellow style=filled]
20 [label="20: DeclStmt \n n$17=*&str:struct __CFAttributedString * [line 46]\n n$18=_fun_CTFramesetterCreateWithAttributedString(n$17:struct __CFAttributedString *) [line 46]\n *&framesetter:struct __CTFramesetter *=n$18 [line 46]\n REMOVE_TEMPS(n$17,n$18); [line 46]\n NULLIFY(&framesetter,false); [line 46]\n NULLIFY(&str,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"]
20 -> 19 ; 20 -> 22 ;
19 [label="19: Exit MemoryLeakExample_test1: \n " color=yellow style=filled] 19 [label="19: DeclStmt \n n$16=_fun_CFAttributedStringCreateMutable(0:struct __CFAllocator *,0:long ) [line 41]\n *&maString:struct __CFAttributedString *=n$16 [line 41]\n REMOVE_TEMPS(n$16); [line 41]\n " shape="box"]
18 [label="18: Start MemoryLeakExample_test1:\nFormals: str:struct __CFAttributedString *\nLocals: framesetter:struct __CTFramesetter * \n DECLARE_LOCALS(&return,&framesetter); [line 45]\n NULLIFY(&framesetter,false); [line 45]\n " color=yellow style=filled] 19 -> 18 ;
18 [label="18: Call _fun___objc_release_cf \n n$15=*&maString:struct __CFAttributedString * [line 42]\n _fun___objc_release_cf(1:_Bool ,n$15:void *) [line 42]\n REMOVE_TEMPS(n$15); [line 42]\n NULLIFY(&maString,false); [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"]
18 -> 20 ; 18 -> 17 ;
17 [label="17: DeclStmt \n n$16=_fun_CFAttributedStringCreateMutable(0:struct __CFAllocator *,0:long ) [line 41]\n *&maString:struct __CFAttributedString *=n$16 [line 41]\n REMOVE_TEMPS(n$16); [line 41]\n " shape="box"] 17 [label="17: Exit MemoryLeakExample_measureFrameSizeForTextNoLeak \n " color=yellow style=filled]
17 -> 16 ; 16 [label="16: Start MemoryLeakExample_measureFrameSizeForTextNoLeak\nFormals: \nLocals: maString:struct __CFAttributedString * \n DECLARE_LOCALS(&return,&maString); [line 39]\n NULLIFY(&maString,false); [line 39]\n " color=yellow style=filled]
16 [label="16: Call _fun___objc_release_cf \n n$15=*&maString:struct __CFAttributedString * [line 42]\n _fun___objc_release_cf(1:_Bool ,n$15:void *) [line 42]\n REMOVE_TEMPS(n$15); [line 42]\n NULLIFY(&maString,false); [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"]
16 -> 15 ; 16 -> 19 ;
15 [label="15: Exit MemoryLeakExample_measureFrameSizeForTextNoLeak \n " color=yellow style=filled] 15 [label="15: DeclStmt \n n$14=_fun_CFAttributedStringCreateMutable(0:struct __CFAllocator *,0:long ) [line 36]\n *&maString:struct __CFAttributedString *=n$14 [line 36]\n REMOVE_TEMPS(n$14); [line 36]\n NULLIFY(&maString,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"]
14 [label="14: Start MemoryLeakExample_measureFrameSizeForTextNoLeak\nFormals: \nLocals: maString:struct __CFAttributedString * \n DECLARE_LOCALS(&return,&maString); [line 39]\n NULLIFY(&maString,false); [line 39]\n " color=yellow style=filled] 15 -> 14 ;
14 [label="14: Exit MemoryLeakExample_measureFrameSizeForText \n " color=yellow style=filled]
14 -> 17 ; 13 [label="13: Start MemoryLeakExample_measureFrameSizeForText\nFormals: \nLocals: maString:struct __CFAttributedString * \n DECLARE_LOCALS(&return,&maString); [line 34]\n NULLIFY(&maString,false); [line 34]\n " color=yellow style=filled]
13 [label="13: DeclStmt \n n$14=_fun_CFAttributedStringCreateMutable(0:struct __CFAllocator *,0:long ) [line 36]\n *&maString:struct __CFAttributedString *=n$14 [line 36]\n REMOVE_TEMPS(n$14); [line 36]\n NULLIFY(&maString,false); [line 36]\n APPLY_ABSTRACTION; [line 36]\n " shape="box"]
13 -> 12 ; 13 -> 15 ;
12 [label="12: Exit MemoryLeakExample_measureFrameSizeForText \n " color=yellow style=filled] 12 [label="12: DeclStmt \n n$10=*&self:class MemoryLeakExample * [line 30]\n n$11=_fun_MemoryLeakExample_backgroundCoveringView(n$10:class MemoryLeakExample *) [line 30]\n n$12=_fun_UIView_bounds(n$11:class UIView *) [line 30]\n n$13=_fun_CGPathCreateWithRect(n$12:struct CGRect ,0:struct CGAffineTransform *) [line 30]\n *&shadowPath:struct CGPath *=n$13 [line 30]\n REMOVE_TEMPS(n$10,n$11,n$12,n$13); [line 30]\n " shape="box"]
11 [label="11: Start MemoryLeakExample_measureFrameSizeForText\nFormals: \nLocals: maString:struct __CFAttributedString * \n DECLARE_LOCALS(&return,&maString); [line 34]\n NULLIFY(&maString,false); [line 34]\n " color=yellow style=filled] 12 -> 11 ;
11 [label="11: Message Call: setShadowPath: \n n$6=*&self:class MemoryLeakExample * [line 31]\n n$7=_fun_MemoryLeakExample_backgroundCoveringView(n$6:class MemoryLeakExample *) [line 31]\n n$8=_fun_UIView_layer(n$7:class UIView *) [line 31]\n n$9=*&shadowPath:struct CGPath * [line 31]\n _fun_CALayer_setShadowPath:(n$8:class CALayer *,n$9:struct CGPath *) [line 31]\n REMOVE_TEMPS(n$6,n$7,n$8,n$9); [line 31]\n NULLIFY(&self,false); [line 31]\n NULLIFY(&shadowPath,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"]
11 -> 13 ; 11 -> 10 ;
10 [label="10: DeclStmt \n n$10=*&self:class MemoryLeakExample * [line 30]\n n$11=_fun_MemoryLeakExample_backgroundCoveringView(n$10:class MemoryLeakExample *) [line 30]\n n$12=_fun_UIView_bounds(n$11:class UIView *) [line 30]\n n$13=_fun_CGPathCreateWithRect(n$12:struct CGRect ,0:struct CGAffineTransform *) [line 30]\n *&shadowPath:struct CGPath *=n$13 [line 30]\n REMOVE_TEMPS(n$10,n$11,n$12,n$13); [line 30]\n " shape="box"] 10 [label="10: Exit MemoryLeakExample_test \n " color=yellow style=filled]
10 -> 9 ; 9 [label="9: Start MemoryLeakExample_test\nFormals: self:class MemoryLeakExample *\nLocals: shadowPath:struct CGPath * \n DECLARE_LOCALS(&return,&shadowPath); [line 28]\n NULLIFY(&shadowPath,false); [line 28]\n " color=yellow style=filled]
9 [label="9: Message Call: setShadowPath: \n n$6=*&self:class MemoryLeakExample * [line 31]\n n$7=_fun_MemoryLeakExample_backgroundCoveringView(n$6:class MemoryLeakExample *) [line 31]\n n$8=_fun_UIView_layer(n$7:class UIView *) [line 31]\n n$9=*&shadowPath:struct CGPath * [line 31]\n _fun_CALayer_setShadowPath:(n$8:class CALayer *,n$9:struct CGPath *) [line 31]\n REMOVE_TEMPS(n$6,n$7,n$8,n$9); [line 31]\n NULLIFY(&self,false); [line 31]\n NULLIFY(&shadowPath,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"]
9 -> 8 ; 9 -> 12 ;
8 [label="8: Exit MemoryLeakExample_test \n " color=yellow style=filled] 8 [label="8: DeclStmt \n n$5=_fun___objc_alloc_no_fail(sizeof(class UIView ):unsigned long ) [line 20]\n *&attachmentContainerView:class UIView *=n$5 [line 20]\n REMOVE_TEMPS(n$5); [line 20]\n " shape="box"]
7 [label="7: Start MemoryLeakExample_test\nFormals: self:class MemoryLeakExample *\nLocals: shadowPath:struct CGPath * \n DECLARE_LOCALS(&return,&shadowPath); [line 28]\n NULLIFY(&shadowPath,false); [line 28]\n " color=yellow style=filled] 8 -> 7 ;
7 [label="7: DeclStmt \n n$2=*&attachmentContainerView:class UIView * [line 22]\n n$3=_fun_UIView_bounds(n$2:class UIView *) [line 22]\n n$4=_fun_CGPathCreateWithRect(n$3:struct CGRect ,0:struct CGAffineTransform *) [line 22]\n *&shadowPath:struct CGPath *=n$4 [line 22]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 22]\n " shape="box"]
7 -> 10 ; 7 -> 6 ;
6 [label="6: DeclStmt \n n$5=_fun___objc_alloc_no_fail(sizeof(class UIView ):unsigned long ) [line 20]\n *&attachmentContainerView:class UIView *=n$5 [line 20]\n REMOVE_TEMPS(n$5); [line 20]\n " shape="box"] 6 [label="6: Call _fun_CGPathRelease \n n$1=*&shadowPath:struct CGPath * [line 24]\n _fun_CGPathRelease(n$1:struct CGPath *) [line 24]\n REMOVE_TEMPS(n$1); [line 24]\n NULLIFY(&shadowPath,false); [line 24]\n " shape="box"]
6 -> 5 ; 6 -> 5 ;
5 [label="5: DeclStmt \n n$2=*&attachmentContainerView:class UIView * [line 22]\n n$3=_fun_UIView_bounds(n$2:class UIView *) [line 22]\n n$4=_fun_CGPathCreateWithRect(n$3:struct CGRect ,0:struct CGAffineTransform *) [line 22]\n *&shadowPath:struct CGPath *=n$4 [line 22]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 22]\n " shape="box"] 5 [label="5: Message Call: release \n n$0=*&attachmentContainerView:class UIView * [line 25]\n _fun___objc_release(n$0:class UIView *) [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n NULLIFY(&attachmentContainerView,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"]
5 -> 4 ; 5 -> 4 ;
4 [label="4: Call _fun_CGPathRelease \n n$1=*&shadowPath:struct CGPath * [line 24]\n _fun_CGPathRelease(n$1:struct CGPath *) [line 24]\n REMOVE_TEMPS(n$1); [line 24]\n NULLIFY(&shadowPath,false); [line 24]\n " shape="box"] 4 [label="4: Exit MemoryLeakExample_layoutSubviews \n " color=yellow style=filled]
4 -> 3 ; 3 [label="3: Start MemoryLeakExample_layoutSubviews\nFormals: self:class MemoryLeakExample *\nLocals: shadowPath:struct CGPath * attachmentContainerView:class UIView * \n DECLARE_LOCALS(&return,&shadowPath,&attachmentContainerView); [line 19]\n NULLIFY(&attachmentContainerView,false); [line 19]\n NULLIFY(&self,false); [line 19]\n NULLIFY(&shadowPath,false); [line 19]\n " color=yellow style=filled]
3 [label="3: Message Call: release \n n$0=*&attachmentContainerView:class UIView * [line 25]\n _fun___objc_release(n$0:class UIView *) [line 25]\n REMOVE_TEMPS(n$0); [line 25]\n NULLIFY(&attachmentContainerView,false); [line 25]\n APPLY_ABSTRACTION; [line 25]\n " shape="box"]
3 -> 2 ; 3 -> 8 ;
2 [label="2: Exit MemoryLeakExample_layoutSubviews \n " color=yellow style=filled] 2 [label="2: Exit MemoryLeakExample_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start MemoryLeakExample_layoutSubviews\nFormals: self:class MemoryLeakExample *\nLocals: shadowPath:struct CGPath * attachmentContainerView:class UIView * \n DECLARE_LOCALS(&return,&shadowPath,&attachmentContainerView); [line 19]\n NULLIFY(&attachmentContainerView,false); [line 19]\n NULLIFY(&self,false); [line 19]\n NULLIFY(&shadowPath,false); [line 19]\n " color=yellow style=filled] 1 [label="1: Start MemoryLeakExample_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 6 ; 1 -> 2 ;
} }

@ -1,42 +1,49 @@
digraph iCFG { digraph iCFG {
13 [label="13: Call _fun___infer_assume \n n$1=*&callback:_fn_ (*) [line 46]\n n$2=_fun___infer_assume((n$1 != 0):_fn_ (*)) [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n " shape="box"] 15 [label="15: Call _fun___infer_assume \n n$1=*&callback:_fn_ (*) [line 46]\n n$2=_fun___infer_assume((n$1 != 0):_fn_ (*)) [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n " shape="box"]
13 -> 12 ; 15 -> 14 ;
12 [label="12: Call n$0 \n n$0=*&callback:_fn_ (*) [line 46]\n n$0(0:class NSError *,0:struct objc_object *) [line 46]\n REMOVE_TEMPS(n$0); [line 46]\n NULLIFY(&callback,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] 14 [label="14: Call n$0 \n n$0=*&callback:_fn_ (*) [line 46]\n n$0(0:class NSError *,0:struct objc_object *) [line 46]\n REMOVE_TEMPS(n$0); [line 46]\n NULLIFY(&callback,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"]
12 -> 11 ; 14 -> 13 ;
11 [label="11: Exit test \n " color=yellow style=filled] 13 [label="13: Exit test \n " color=yellow style=filled]
10 [label="10: Start test\nFormals: callback:_fn_ (*)\nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled] 12 [label="12: Start test\nFormals: callback:_fn_ (*)\nLocals: \n DECLARE_LOCALS(&return); [line 46]\n " color=yellow style=filled]
10 -> 13 ; 12 -> 15 ;
9 [label="9: Call _fun___infer_assume \n n$5=*&a:class A * [line 38]\n n$6=_fun___infer_assume((n$5 != 0):class A *) [line 38]\n REMOVE_TEMPS(n$5,n$6); [line 38]\n " shape="box"] 11 [label="11: Call _fun___infer_assume \n n$5=*&a:class A * [line 38]\n n$6=_fun___infer_assume((n$5 != 0):class A *) [line 38]\n REMOVE_TEMPS(n$5,n$6); [line 38]\n " shape="box"]
11 -> 10 ;
10 [label="10: DeclStmt \n n$3=*&a:class A * [line 39]\n n$4=_fun_A_getA(n$3:class A *) virtual [line 39]\n _fun___objc_retain(n$4:class A *) [line 39]\n *&a1:class A *=n$4 [line 39]\n REMOVE_TEMPS(n$3,n$4); [line 39]\n NULLIFY(&a,false); [line 39]\n " shape="box"]
10 -> 9 ;
9 [label="9: DeclStmt \n n$1=*&a1:class A * [line 40]\n n$2=*n$1.x:int [line 40]\n *&y:int =n$2 [line 40]\n REMOVE_TEMPS(n$1,n$2); [line 40]\n NULLIFY(&a1,false); [line 40]\n NULLIFY(&y,false); [line 40]\n " shape="box"]
9 -> 8 ; 9 -> 8 ;
8 [label="8: DeclStmt \n n$3=*&a:class A * [line 39]\n n$4=_fun_A_getA(n$3:class A *) virtual [line 39]\n _fun___objc_retain(n$4:class A *) [line 39]\n *&a1:class A *=n$4 [line 39]\n REMOVE_TEMPS(n$3,n$4); [line 39]\n NULLIFY(&a,false); [line 39]\n " shape="box"] 8 [label="8: Return Stmt \n n$0=*&self:class C * [line 41]\n *&return:struct objc_object *=n$0 [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n NULLIFY(&self,false); [line 41]\n APPLY_ABSTRACTION; [line 41]\n " shape="box"]
8 -> 7 ; 8 -> 7 ;
7 [label="7: DeclStmt \n n$1=*&a1:class A * [line 40]\n n$2=*n$1.x:int [line 40]\n *&y:int =n$2 [line 40]\n REMOVE_TEMPS(n$1,n$2); [line 40]\n NULLIFY(&a1,false); [line 40]\n NULLIFY(&y,false); [line 40]\n " shape="box"] 7 [label="7: Exit C_initWithCoder:and: \n " color=yellow style=filled]
7 -> 6 ; 6 [label="6: Start C_initWithCoder:and:\nFormals: self:class C * aDecoder:class NSString * a:class A *\nLocals: y:int a1:class A * \n DECLARE_LOCALS(&return,&y,&a1); [line 38]\n NULLIFY(&a1,false); [line 38]\n NULLIFY(&aDecoder,false); [line 38]\n NULLIFY(&y,false); [line 38]\n " color=yellow style=filled]
6 [label="6: Return Stmt \n n$0=*&self:class C * [line 41]\n *&return:struct objc_object *=n$0 [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n NULLIFY(&self,false); [line 41]\n APPLY_ABSTRACTION; [line 41]\n " shape="box"]
6 -> 5 ; 6 -> 11 ;
5 [label="5: Exit C_initWithCoder:and: \n " color=yellow style=filled] 5 [label="5: Exit C_frontendChecks \n " color=yellow style=filled]
4 [label="4: Start C_initWithCoder:and:\nFormals: self:class C * aDecoder:class NSString * a:class A *\nLocals: y:int a1:class A * \n DECLARE_LOCALS(&return,&y,&a1); [line 38]\n NULLIFY(&a1,false); [line 38]\n NULLIFY(&aDecoder,false); [line 38]\n NULLIFY(&y,false); [line 38]\n " color=yellow style=filled] 4 [label="4: Start C_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
4 -> 9 ; 4 -> 5 ;
3 [label="3: Return Stmt \n n$0=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 26]\n n$1=_fun_NSObject_init(n$0:class A *) virtual [line 26]\n *&return:class A *=n$1 [line 26]\n n$2=_fun___set_autorelease_attribute(n$1:class A *) [line 26]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] 3 [label="3: Return Stmt \n n$0=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 26]\n n$1=_fun_NSObject_init(n$0:class A *) virtual [line 26]\n *&return:class A *=n$1 [line 26]\n n$2=_fun___set_autorelease_attribute(n$1:class A *) [line 26]\n REMOVE_TEMPS(n$0,n$1,n$2); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"]

@ -1,102 +1,109 @@
digraph iCFG { digraph iCFG {
26 [label="26: DeclStmt \n n$3=_fun_A_sharedInstance() [line 43]\n *&b:class A *=n$3 [line 43]\n REMOVE_TEMPS(n$3); [line 43]\n " shape="box"] 28 [label="28: DeclStmt \n n$3=_fun_A_sharedInstance() [line 43]\n *&b:class A *=n$3 [line 43]\n REMOVE_TEMPS(n$3); [line 43]\n " shape="box"]
26 -> 25 ; 28 -> 27 ;
25 [label="25: DeclStmt \n *&p:int *=0 [line 44]\n " shape="box"] 27 [label="27: DeclStmt \n *&p:int *=0 [line 44]\n " shape="box"]
27 -> 22 ;
26 [label="26: Return Stmt \n NULLIFY(&p,false); [line 48]\n *&return:int =0 [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"]
26 -> 20 ;
25 [label="25: Return Stmt \n n$1=*&p:int * [line 46]\n n$2=*n$1:int [line 46]\n *&return:int =n$2 [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n NULLIFY(&p,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"]
25 -> 20 ; 25 -> 20 ;
24 [label="24: Return Stmt \n NULLIFY(&p,false); [line 48]\n *&return:int =0 [line 48]\n APPLY_ABSTRACTION; [line 48]\n " shape="box"] 24 [label="24: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"]
24 -> 18 ; 24 -> 26 ;
23 [label="23: Return Stmt \n n$1=*&p:int * [line 46]\n n$2=*n$1:int [line 46]\n *&return:int =n$2 [line 46]\n REMOVE_TEMPS(n$1,n$2); [line 46]\n NULLIFY(&p,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] 23 [label="23: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"]
23 -> 18 ; 23 -> 25 ;
22 [label="22: Prune (false branch) \n PRUNE(((n$0 == 0) == 0), false); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"] 22 [label="22: BinaryOperatorStmt: EQ \n n$0=*&b:class A * [line 45]\n NULLIFY(&b,false); [line 45]\n " shape="box"]
22 -> 23 ;
22 -> 24 ; 22 -> 24 ;
21 [label="21: Prune (true branch) \n PRUNE(((n$0 == 0) != 0), true); [line 45]\n REMOVE_TEMPS(n$0); [line 45]\n " shape="invhouse"] 21 [label="21: + \n NULLIFY(&b,false); [line 45]\n NULLIFY(&p,false); [line 45]\n " ]
21 -> 23 ; 21 -> 20 ;
20 [label="20: BinaryOperatorStmt: EQ \n n$0=*&b:class A * [line 45]\n NULLIFY(&b,false); [line 45]\n " shape="box"] 20 [label="20: Exit main \n " color=yellow style=filled]
20 -> 21 ; 19 [label="19: Start main\nFormals: \nLocals: p:int * b:class A * \n DECLARE_LOCALS(&return,&p,&b); [line 42]\n NULLIFY(&b,false); [line 42]\n NULLIFY(&p,false); [line 42]\n " color=yellow style=filled]
20 -> 22 ;
19 [label="19: + \n NULLIFY(&b,false); [line 45]\n NULLIFY(&p,false); [line 45]\n " ]
19 -> 18 ; 19 -> 28 ;
18 [label="18: Exit main \n " color=yellow style=filled] 18 [label="18: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans______2); [line 34]\n n$11=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans______2 ):unsigned long ) [line 34]\n *&__objc_anonymous_block_A_trans______2:class __objc_anonymous_block_A_trans______2 =n$11 [line 34]\n n$12=*&#GB$A_trans_sharedInstance:struct objc_object * [line 34]\n *n$11.A_trans_sharedInstance:struct objc_object *=n$12 [line 34]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans______2) [line 34]\n REMOVE_TEMPS(n$11,n$12); [line 34]\n " shape="box"]
17 [label="17: Start main\nFormals: \nLocals: p:int * b:class A * \n DECLARE_LOCALS(&return,&p,&b); [line 42]\n NULLIFY(&b,false); [line 42]\n NULLIFY(&p,false); [line 42]\n " color=yellow style=filled] 18 -> 14 ;
17 [label="17: BinaryOperatorStmt: Assign \n n$9=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 35]\n n$10=_fun_A_init(n$9:class A *) virtual [line 35]\n *&#GB$A_trans_sharedInstance:struct objc_object *=n$10 [line 35]\n REMOVE_TEMPS(n$9,n$10); [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"]
17 -> 26 ; 17 -> 16 ;
16 [label="16: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans______2); [line 34]\n n$11=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans______2 ):unsigned long ) [line 34]\n *&__objc_anonymous_block_A_trans______2:class __objc_anonymous_block_A_trans______2 =n$11 [line 34]\n n$12=*&#GB$A_trans_sharedInstance:struct objc_object * [line 34]\n *n$11.A_trans_sharedInstance:struct objc_object *=n$12 [line 34]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans______2) [line 34]\n REMOVE_TEMPS(n$11,n$12); [line 34]\n " shape="box"] 16 [label="16: Exit __objc_anonymous_block_A_trans______2 \n " color=yellow style=filled]
16 -> 12 ; 15 [label="15: Start __objc_anonymous_block_A_trans______2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 34]\n " color=yellow style=filled]
15 [label="15: BinaryOperatorStmt: Assign \n n$9=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 35]\n n$10=_fun_A_init(n$9:class A *) virtual [line 35]\n *&#GB$A_trans_sharedInstance:struct objc_object *=n$10 [line 35]\n REMOVE_TEMPS(n$9,n$10); [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"]
15 -> 14 ; 15 -> 17 ;
14 [label="14: Exit __objc_anonymous_block_A_trans______2 \n " color=yellow style=filled] 14 [label="14: Call n$8 \n n$8=*&dummy_block:_fn_ (*) [line 37]\n n$8() [line 37]\n REMOVE_TEMPS(n$8); [line 37]\n NULLIFY(&dummy_block,false); [line 37]\n " shape="box"]
13 [label="13: Start __objc_anonymous_block_A_trans______2\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 34]\n " color=yellow style=filled] 14 -> 13 ;
13 [label="13: Return Stmt \n n$7=*&#GB$A_trans_sharedInstance:struct objc_object * [line 38]\n *&return:struct objc_object *=n$7 [line 38]\n REMOVE_TEMPS(n$7); [line 38]\n NULLIFY(&__objc_anonymous_block_A_trans______2,true); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"]
13 -> 15 ; 13 -> 12 ;
12 [label="12: Call n$8 \n n$8=*&dummy_block:_fn_ (*) [line 37]\n n$8() [line 37]\n REMOVE_TEMPS(n$8); [line 37]\n NULLIFY(&dummy_block,false); [line 37]\n " shape="box"] 12 [label="12: Exit A_trans \n " color=yellow style=filled]
12 -> 11 ; 11 [label="11: Start A_trans\nFormals: \nLocals: dummy_block:_fn_ (*) \n DECLARE_LOCALS(&return,&dummy_block); [line 32]\n NULLIFY(&dummy_block,false); [line 32]\n " color=yellow style=filled]
11 [label="11: Return Stmt \n n$7=*&#GB$A_trans_sharedInstance:struct objc_object * [line 38]\n *&return:struct objc_object *=n$7 [line 38]\n REMOVE_TEMPS(n$7); [line 38]\n NULLIFY(&__objc_anonymous_block_A_trans______2,true); [line 38]\n APPLY_ABSTRACTION; [line 38]\n " shape="box"]
11 -> 10 ; 11 -> 18 ;
10 [label="10: Exit A_trans \n " color=yellow style=filled] 10 [label="10: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 26]\n n$5=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 26]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$5 [line 26]\n n$6=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 26]\n *n$5.A_sharedInstance_sharedInstance:struct objc_object *=n$6 [line 26]\n *&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*)=(_fun___objc_anonymous_block_A_sharedInstance______1) [line 26]\n REMOVE_TEMPS(n$5,n$6); [line 26]\n " shape="box"]
9 [label="9: Start A_trans\nFormals: \nLocals: dummy_block:_fn_ (*) \n DECLARE_LOCALS(&return,&dummy_block); [line 32]\n NULLIFY(&dummy_block,false); [line 32]\n " color=yellow style=filled] 10 -> 6 ;
9 [label="9: BinaryOperatorStmt: Assign \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 27]\n n$4=_fun_A_init(n$3:class A *) virtual [line 27]\n *&#GB$A_sharedInstance_sharedInstance:struct objc_object *=n$4 [line 27]\n REMOVE_TEMPS(n$3,n$4); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"]
9 -> 16 ; 9 -> 8 ;
8 [label="8: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 26]\n n$5=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 26]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$5 [line 26]\n n$6=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 26]\n *n$5.A_sharedInstance_sharedInstance:struct objc_object *=n$6 [line 26]\n *&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*)=(_fun___objc_anonymous_block_A_sharedInstance______1) [line 26]\n REMOVE_TEMPS(n$5,n$6); [line 26]\n " shape="box"] 8 [label="8: Exit __objc_anonymous_block_A_sharedInstance______1 \n " color=yellow style=filled]
8 -> 4 ; 7 [label="7: Start __objc_anonymous_block_A_sharedInstance______1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 26]\n " color=yellow style=filled]
7 [label="7: BinaryOperatorStmt: Assign \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 27]\n n$4=_fun_A_init(n$3:class A *) virtual [line 27]\n *&#GB$A_sharedInstance_sharedInstance:struct objc_object *=n$4 [line 27]\n REMOVE_TEMPS(n$3,n$4); [line 27]\n APPLY_ABSTRACTION; [line 27]\n " shape="box"]
7 -> 6 ; 7 -> 9 ;
6 [label="6: Exit __objc_anonymous_block_A_sharedInstance______1 \n " color=yellow style=filled] 6 [label="6: Call n$1 \n n$1=*&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*) [line 26]\n n$2=n$1() [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&infer___objc_anonymous_block_A_sharedInstance______1,false); [line 26]\n " shape="box"]
5 [label="5: Start __objc_anonymous_block_A_sharedInstance______1\nFormals: \nLocals: \n DECLARE_LOCALS(&return); [line 26]\n " color=yellow style=filled] 6 -> 5 ;
5 [label="5: Return Stmt \n n$0=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 29]\n *&return:struct objc_object *=n$0 [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n NULLIFY(&__objc_anonymous_block_A_sharedInstance______1,true); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"]
5 -> 7 ; 5 -> 4 ;
4 [label="4: Call n$1 \n n$1=*&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*) [line 26]\n n$2=n$1() [line 26]\n REMOVE_TEMPS(n$1,n$2); [line 26]\n NULLIFY(&infer___objc_anonymous_block_A_sharedInstance______1,false); [line 26]\n " shape="box"] 4 [label="4: Exit A_sharedInstance \n " color=yellow style=filled]
4 -> 3 ; 3 [label="3: Start A_sharedInstance\nFormals: \nLocals: infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*) \n DECLARE_LOCALS(&return,&infer___objc_anonymous_block_A_sharedInstance______1); [line 23]\n NULLIFY(&infer___objc_anonymous_block_A_sharedInstance______1,false); [line 23]\n " color=yellow style=filled]
3 [label="3: Return Stmt \n n$0=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 29]\n *&return:struct objc_object *=n$0 [line 29]\n REMOVE_TEMPS(n$0); [line 29]\n NULLIFY(&__objc_anonymous_block_A_sharedInstance______1,true); [line 29]\n APPLY_ABSTRACTION; [line 29]\n " shape="box"]
3 -> 2 ; 3 -> 10 ;
2 [label="2: Exit A_sharedInstance \n " color=yellow style=filled] 2 [label="2: Exit A_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start A_sharedInstance\nFormals: \nLocals: infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*) \n DECLARE_LOCALS(&return,&infer___objc_anonymous_block_A_sharedInstance______1); [line 23]\n NULLIFY(&infer___objc_anonymous_block_A_sharedInstance______1,false); [line 23]\n " color=yellow style=filled] 1 [label="1: Start A_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 8 ; 1 -> 2 ;
} }

@ -1,65 +1,72 @@
digraph iCFG { digraph iCFG {
16 [label="16: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 39]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 39]\n *&a:class A *=n$4 [line 39]\n REMOVE_TEMPS(n$3,n$4); [line 39]\n " shape="box"] 18 [label="18: DeclStmt \n n$3=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 39]\n n$4=_fun_NSObject_init(n$3:class A *) virtual [line 39]\n *&a:class A *=n$4 [line 39]\n REMOVE_TEMPS(n$3,n$4); [line 39]\n " shape="box"]
18 -> 17 ;
17 [label="17: Message Call: setLast_name: \n n$1=*&a:class A * [line 40]\n n$2=*&a2:class A * [line 40]\n _fun_A_setLast_name:(n$1:class A *,n$2:class A *) [line 40]\n REMOVE_TEMPS(n$1,n$2); [line 40]\n NULLIFY(&a2,false); [line 40]\n " shape="box"]
17 -> 16 ;
16 [label="16: Message Call: release \n n$0=*&a:class A * [line 41]\n _fun___objc_release(n$0:class A *) [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n NULLIFY(&a,false); [line 41]\n " shape="box"]
16 -> 15 ; 16 -> 15 ;
15 [label="15: Message Call: setLast_name: \n n$1=*&a:class A * [line 40]\n n$2=*&a2:class A * [line 40]\n _fun_A_setLast_name:(n$1:class A *,n$2:class A *) [line 40]\n REMOVE_TEMPS(n$1,n$2); [line 40]\n NULLIFY(&a2,false); [line 40]\n " shape="box"] 15 [label="15: Return Stmt \n *&return:int =0 [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"]
15 -> 14 ; 15 -> 14 ;
14 [label="14: Message Call: release \n n$0=*&a:class A * [line 41]\n _fun___objc_release(n$0:class A *) [line 41]\n REMOVE_TEMPS(n$0); [line 41]\n NULLIFY(&a,false); [line 41]\n " shape="box"] 14 [label="14: Exit test \n " color=yellow style=filled]
14 -> 13 ; 13 [label="13: Start test\nFormals: a2:class A *\nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 38]\n NULLIFY(&a,false); [line 38]\n " color=yellow style=filled]
13 [label="13: Return Stmt \n *&return:int =0 [line 42]\n APPLY_ABSTRACTION; [line 42]\n " shape="box"]
13 -> 12 ; 13 -> 18 ;
12 [label="12: Exit test \n " color=yellow style=filled] 12 [label="12: DeclStmt \n n$11=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 27]\n n$12=_fun_NSObject_init(n$11:class A *) virtual [line 27]\n *&other:class A *=n$12 [line 27]\n REMOVE_TEMPS(n$11,n$12); [line 27]\n " shape="box"]
11 [label="11: Start test\nFormals: a2:class A *\nLocals: a:class A * \n DECLARE_LOCALS(&return,&a); [line 38]\n NULLIFY(&a,false); [line 38]\n " color=yellow style=filled] 12 -> 7 ;
12 -> 8 ;
11 [label="11: BinaryOperatorStmt: Assign \n n$8=*&other:class A * [line 29]\n n$9=*&self:class A * [line 29]\n n$10=*n$9._name:class A * [line 29]\n *n$8._name:class A *=n$10 [line 29]\n REMOVE_TEMPS(n$8,n$9,n$10); [line 29]\n " shape="box"]
11 -> 16 ; 11 -> 10 ;
10 [label="10: DeclStmt \n n$11=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 27]\n n$12=_fun_NSObject_init(n$11:class A *) virtual [line 27]\n *&other:class A *=n$12 [line 27]\n REMOVE_TEMPS(n$11,n$12); [line 27]\n " shape="box"] 10 [label="10: BinaryOperatorStmt: Assign \n n$5=*&other:class A * [line 30]\n n$6=*&self:class A * [line 30]\n n$7=*n$6._last_name:class A * [line 30]\n *n$5._last_name:class A *=n$7 [line 30]\n REMOVE_TEMPS(n$5,n$6,n$7); [line 30]\n " shape="box"]
10 -> 5 ; 10 -> 9 ;
10 -> 6 ; 9 [label="9: BinaryOperatorStmt: Assign \n n$2=*&other:class A * [line 31]\n n$3=*&self:class A * [line 31]\n n$4=*n$3._child:class A * [line 31]\n *n$2._child:class A *=n$4 [line 31]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 31]\n NULLIFY(&self,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"]
9 [label="9: BinaryOperatorStmt: Assign \n n$8=*&other:class A * [line 29]\n n$9=*&self:class A * [line 29]\n n$10=*n$9._name:class A * [line 29]\n *n$8._name:class A *=n$10 [line 29]\n REMOVE_TEMPS(n$8,n$9,n$10); [line 29]\n " shape="box"]
9 -> 8 ; 9 -> 6 ;
8 [label="8: BinaryOperatorStmt: Assign \n n$5=*&other:class A * [line 30]\n n$6=*&self:class A * [line 30]\n n$7=*n$6._last_name:class A * [line 30]\n *n$5._last_name:class A *=n$7 [line 30]\n REMOVE_TEMPS(n$5,n$6,n$7); [line 30]\n " shape="box"] 8 [label="8: Prune (false branch) \n n$1=*&other:class A * [line 28]\n PRUNE((n$1 == 0), false); [line 28]\n REMOVE_TEMPS(n$1); [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="invhouse"]
8 -> 7 ; 8 -> 6 ;
7 [label="7: BinaryOperatorStmt: Assign \n n$2=*&other:class A * [line 31]\n n$3=*&self:class A * [line 31]\n n$4=*n$3._child:class A * [line 31]\n *n$2._child:class A *=n$4 [line 31]\n REMOVE_TEMPS(n$2,n$3,n$4); [line 31]\n NULLIFY(&self,false); [line 31]\n APPLY_ABSTRACTION; [line 31]\n " shape="box"] 7 [label="7: Prune (true branch) \n n$1=*&other:class A * [line 28]\n PRUNE((n$1 != 0), true); [line 28]\n REMOVE_TEMPS(n$1); [line 28]\n " shape="invhouse"]
7 -> 4 ; 7 -> 11 ;
6 [label="6: Prune (false branch) \n n$1=*&other:class A * [line 28]\n PRUNE((n$1 == 0), false); [line 28]\n REMOVE_TEMPS(n$1); [line 28]\n APPLY_ABSTRACTION; [line 28]\n " shape="invhouse"] 6 [label="6: + \n " ]
6 -> 4 ; 6 -> 5 ;
5 [label="5: Prune (true branch) \n n$1=*&other:class A * [line 28]\n PRUNE((n$1 != 0), true); [line 28]\n REMOVE_TEMPS(n$1); [line 28]\n " shape="invhouse"] 5 [label="5: Return Stmt \n NULLIFY(&self,false); [line 33]\n n$0=*&other:class A * [line 33]\n *&return:class A *=n$0 [line 33]\n REMOVE_TEMPS(n$0); [line 33]\n NULLIFY(&other,false); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"]
5 -> 9 ; 5 -> 4 ;
4 [label="4: + \n " ] 4 [label="4: Exit A_copy \n " color=yellow style=filled]
4 -> 3 ; 3 [label="3: Start A_copy\nFormals: self:class A *\nLocals: other:class A * \n DECLARE_LOCALS(&return,&other); [line 26]\n NULLIFY(&other,false); [line 26]\n " color=yellow style=filled]
3 [label="3: Return Stmt \n NULLIFY(&self,false); [line 33]\n n$0=*&other:class A * [line 33]\n *&return:class A *=n$0 [line 33]\n REMOVE_TEMPS(n$0); [line 33]\n NULLIFY(&other,false); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"]
3 -> 2 ; 3 -> 12 ;
2 [label="2: Exit A_copy \n " color=yellow style=filled] 2 [label="2: Exit A_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start A_copy\nFormals: self:class A *\nLocals: other:class A * \n DECLARE_LOCALS(&return,&other); [line 26]\n NULLIFY(&other,false); [line 26]\n " color=yellow style=filled] 1 [label="1: Start A_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 10 ; 1 -> 2 ;
} }

@ -0,0 +1,9 @@
digraph iCFG {
2 [label="2: Exit ASDisplayNode_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start ASDisplayNode_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 2 ;
}

@ -1,13 +1,20 @@
digraph iCFG { digraph iCFG {
3 [label="3: BinaryOperatorStmt: Assign \n n$0=*&self:class PropertyImplSetter * [line 15]\n *n$0._maximumFileSize:int =0 [line 15]\n REMOVE_TEMPS(n$0); [line 15]\n NULLIFY(&self,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"] 5 [label="5: BinaryOperatorStmt: Assign \n n$0=*&self:class PropertyImplSetter * [line 15]\n *n$0._maximumFileSize:int =0 [line 15]\n REMOVE_TEMPS(n$0); [line 15]\n NULLIFY(&self,false); [line 15]\n APPLY_ABSTRACTION; [line 15]\n " shape="box"]
3 -> 2 ; 5 -> 4 ;
2 [label="2: Exit PropertyImplSetter_setMaximumFileSize: \n " color=yellow style=filled] 4 [label="4: Exit PropertyImplSetter_setMaximumFileSize: \n " color=yellow style=filled]
1 [label="1: Start PropertyImplSetter_setMaximumFileSize:\nFormals: self:class PropertyImplSetter * newMaximumFileSize:int \nLocals: \n DECLARE_LOCALS(&return); [line 14]\n NULLIFY(&newMaximumFileSize,false); [line 14]\n " color=yellow style=filled] 3 [label="3: Start PropertyImplSetter_setMaximumFileSize:\nFormals: self:class PropertyImplSetter * newMaximumFileSize:int \nLocals: \n DECLARE_LOCALS(&return); [line 14]\n NULLIFY(&newMaximumFileSize,false); [line 14]\n " color=yellow style=filled]
1 -> 3 ; 3 -> 5 ;
2 [label="2: Exit PropertyImplSetter_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start PropertyImplSetter_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 2 ;
} }

@ -1,13 +1,20 @@
digraph iCFG { digraph iCFG {
3 [label="3: Return Stmt \n n$0=*&target:class A * [line 19]\n n$1=_fun_A_x(n$0:class A *) [line 19]\n *&return:int =n$1 [line 19]\n REMOVE_TEMPS(n$0,n$1); [line 19]\n NULLIFY(&target,false); [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"] 5 [label="5: Return Stmt \n n$0=*&target:class A * [line 19]\n n$1=_fun_A_x(n$0:class A *) [line 19]\n *&return:int =n$1 [line 19]\n REMOVE_TEMPS(n$0,n$1); [line 19]\n NULLIFY(&target,false); [line 19]\n APPLY_ABSTRACTION; [line 19]\n " shape="box"]
3 -> 2 ; 5 -> 4 ;
2 [label="2: Exit A_addTarget: \n " color=yellow style=filled] 4 [label="4: Exit A_addTarget: \n " color=yellow style=filled]
1 [label="1: Start A_addTarget:\nFormals: self:class A * target:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n NULLIFY(&self,false); [line 18]\n " color=yellow style=filled] 3 [label="3: Start A_addTarget:\nFormals: self:class A * target:class A *\nLocals: \n DECLARE_LOCALS(&return); [line 18]\n NULLIFY(&self,false); [line 18]\n " color=yellow style=filled]
1 -> 3 ; 3 -> 5 ;
2 [label="2: Exit A_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start A_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 2 ;
} }

@ -0,0 +1,9 @@
digraph iCFG {
2 [label="2: Exit AClass_frontendChecks \n " color=yellow style=filled]
1 [label="1: Start AClass_frontendChecks\nFormals: \nLocals: \n " color=yellow style=filled]
1 -> 2 ;
}
Loading…
Cancel
Save