Adding static variables to blocks class to get retain cycles

Summary: public
The static and global variables used in blocks don't appear in the ast as captured.
We need them however to try and find retain cycles involving those variables.
This diff adds a way of collecting the static variables used in blocks and treat them
like we treat other captured variables to find retain  cycles.

Reviewed By: ddino

Differential Revision: D2663727

fb-gh-sync-id: d5b44ec
master
Dulma Rodriguez 9 years ago committed by facebook-github-bot-7
parent 930eaba2d5
commit 87a3d693e1

@ -33,7 +33,7 @@ type t =
is_callee_expression : bool; is_callee_expression : bool;
namespace: string option; (* contains the name of the namespace if we are in the scope of one*) namespace: string option; (* contains the name of the namespace if we are in the scope of one*)
outer_context : t option; (* in case of objc blocks, the context of the method containing the block *) outer_context : t option; (* in case of objc blocks, the context of the method containing the block *)
mutable blocks : Procname.t list (* List of blocks defined in this method *) mutable blocks_static_vars : ((Sil.pvar * Sil.typ) list) Procname.Map.t;
} }
let create_context tenv cg cfg procdesc ns curr_class is_objc_method context_opt = let create_context tenv cg cfg procdesc ns curr_class is_objc_method context_opt =
@ -46,7 +46,7 @@ let create_context tenv cg cfg procdesc ns curr_class is_objc_method context_opt
is_objc_method = is_objc_method; is_objc_method = is_objc_method;
namespace = ns; namespace = ns;
outer_context = context_opt; outer_context = context_opt;
blocks = [] blocks_static_vars = Procname.Map.empty
} }
let get_cfg context = context.cfg let get_cfg context = context.cfg
@ -128,11 +128,29 @@ let create_curr_class tenv class_name =
| [] -> ContextCls (class_name, None, [])) | [] -> ContextCls (class_name, None, []))
| _ -> assert false | _ -> assert false
let rec add_block context block = let add_block_static_var context block_name static_var_typ =
context.blocks <- block :: context.blocks; match context.outer_context, static_var_typ with
match context.outer_context with | Some outer_context, (static_var, typ) when Sil.pvar_is_global static_var ->
| Some outer_context -> add_block outer_context block (let new_static_vars, duplicate =
| None -> () try
let static_vars = Procname.Map.find block_name outer_context.blocks_static_vars in
if IList.mem (
fun (var1, typ1) (var2, typ2) -> Sil.pvar_equal var1 var2
) static_var_typ static_vars then
static_vars, true
else
static_var_typ :: static_vars, false
with Not_found -> [static_var_typ], false in
if not duplicate then
let blocks_static_vars =
Procname.Map.add block_name new_static_vars outer_context.blocks_static_vars in
outer_context.blocks_static_vars <- blocks_static_vars)
| _ -> ()
let static_vars_for_block context block_name =
try Procname.Map.find block_name context.blocks_static_vars
with Not_found -> []
let rec get_outer_procname context = let rec get_outer_procname context =
match context.outer_context with match context.outer_context with

@ -28,7 +28,7 @@ type t =
is_callee_expression : bool; is_callee_expression : bool;
namespace: string option; (* contains the name of the namespace if we are in the scope of one*) namespace: string option; (* contains the name of the namespace if we are in the scope of one*)
outer_context : t option; (* in case of objc blocks, the context of the method containing the block *) outer_context : t option; (* in case of objc blocks, the context of the method containing the block *)
mutable blocks: Procname.t list; (* List of blocks defined in this method *) mutable blocks_static_vars : ((Sil.pvar * Sil.typ) list) Procname.Map.t;
} }
val get_procdesc : t -> Cfg.Procdesc.t val get_procdesc : t -> Cfg.Procdesc.t
@ -58,7 +58,9 @@ val create_context : Sil.tenv -> Cg.t -> Cfg.cfg -> Cfg.Procdesc.t ->
val create_curr_class : Sil.tenv -> string -> curr_class val create_curr_class : Sil.tenv -> string -> curr_class
val add_block : t -> Procname.t -> unit val add_block_static_var : t -> Procname.t -> (Sil.pvar * Sil.typ) -> unit
val static_vars_for_block : t -> Procname.t -> (Sil.pvar * Sil.typ) list
val is_objc_instance : t -> bool val is_objc_instance : t -> bool

@ -252,7 +252,9 @@ let create_local_procdesc cfg tenv ms fbody captured is_objc_inst_method =
let is_generated = CMethod_signature.ms_is_generated ms in let is_generated = CMethod_signature.ms_is_generated ms in
let create_new_procdesc () = let create_new_procdesc () =
let formals = get_formal_parameters tenv ms in let formals = get_formal_parameters tenv ms in
let captured_str = IList.map (fun (s, t, _) -> (Mangled.to_string s, t)) captured in let captured_str = IList.map (
fun (var, t) -> (Mangled.to_string (Sil.pvar_get_name var), t)
) captured in
(* Captured variables for blocks are treated as parameters *) (* Captured variables for blocks are treated as parameters *)
let formals = captured_str @formals in let formals = captured_str @formals in
let source_range = CMethod_signature.ms_get_loc ms in let source_range = CMethod_signature.ms_get_loc ms in
@ -260,7 +262,7 @@ let create_local_procdesc cfg tenv ms fbody captured is_objc_inst_method =
let loc_start = CLocation.get_sil_location_from_range source_range true in let loc_start = CLocation.get_sil_location_from_range source_range true in
let loc_exit = CLocation.get_sil_location_from_range source_range false in let loc_exit = CLocation.get_sil_location_from_range source_range false in
let ret_type = get_return_type tenv ms in let ret_type = get_return_type tenv ms in
let captured' = IList.map (fun (s, t, _) -> (s, t)) captured in let captured' = IList.map (fun (var, t) -> (Sil.pvar_get_name var, t)) captured in
let procdesc = let procdesc =
let proc_attributes = let proc_attributes =
{ (ProcAttributes.default proc_name Config.C_CPP) with { (ProcAttributes.default proc_name Config.C_CPP) with

@ -21,7 +21,7 @@ type method_call_type =
| MCStatic | MCStatic
val create_local_procdesc : Cfg.cfg -> Sil.tenv -> CMethod_signature.method_signature -> val create_local_procdesc : Cfg.cfg -> Sil.tenv -> CMethod_signature.method_signature ->
Clang_ast_t.stmt list -> (Mangled.t * Sil.typ * bool) list -> bool -> bool Clang_ast_t.stmt list -> (Sil.pvar * Sil.typ) list -> bool -> bool
val create_external_procdesc : Cfg.cfg -> Procname.t -> bool -> (Sil.typ * Sil.typ list) option -> unit val create_external_procdesc : Cfg.cfg -> Procname.t -> bool -> (Sil.typ * Sil.typ list) option -> unit

@ -7,7 +7,7 @@
* 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 block_data = CContext.t * Clang_ast_t.type_ptr * Procname.t * (Mangled.t * Sil.typ * bool) list type block_data = CContext.t * Clang_ast_t.type_ptr * Procname.t * (Sil.pvar * Sil.typ) list
type instr_type = [ type instr_type = [
| `ClangStmt of Clang_ast_t.stmt | `ClangStmt of Clang_ast_t.stmt

@ -94,7 +94,8 @@ struct
let tenv = trans_state.context.CContext.tenv in let tenv = trans_state.context.CContext.tenv in
let procdesc = trans_state.context.CContext.procdesc in let procdesc = trans_state.context.CContext.procdesc in
let procname = Cfg.Procdesc.get_proc_name procdesc in let procname = Cfg.Procdesc.get_proc_name procdesc in
let mk_field_from_captured_var (vname, typ, b) = let mk_field_from_captured_var (var, typ) =
let vname = Sil.pvar_get_name var in
let qual_name = Ast_utils.make_qual_name_decl block_name (Mangled.to_string vname) in let qual_name = Ast_utils.make_qual_name_decl block_name (Mangled.to_string vname) in
let fname = General_utils.mk_class_field_name qual_name in let fname = General_utils.mk_class_field_name qual_name in
let item_annot = Sil.item_annotation_empty in let item_annot = Sil.item_annotation_empty in
@ -124,10 +125,10 @@ struct
Cfg.Node.append_instrs_temps n [Sil.Nullify(block_var, loc, true)] []) pred_exit; Cfg.Node.append_instrs_temps n [Sil.Nullify(block_var, loc, true)] []) pred_exit;
[]) in []) in
let set_instr = Sil.Set (Sil.Lvar block_var, block_type, Sil.Var id_block, loc) in let set_instr = Sil.Set (Sil.Lvar block_var, block_type, Sil.Var id_block, loc) in
let ids, captured_instrs = IList.split (IList.map (fun (vname, typ, _) -> let create_field_exp (var, typ) =
let id = Ident.create_fresh Ident.knormal in let id = Ident.create_fresh Ident.knormal in
id, Sil.Letderef(id, Sil.Lvar (Sil.mk_pvar vname procname), typ, loc) id, Sil.Letderef (id, Sil.Lvar var, typ, loc) in
) captured_vars) in let ids, captured_instrs = IList.split (IList.map create_field_exp captured_vars) in
let fields_ids = IList.combine fields ids in let fields_ids = IList.combine fields ids in
let set_fields = IList.map (fun ((f, t, _), id) -> let set_fields = IList.map (fun ((f, t, _), id) ->
Sil.Set (Sil.Lfield (Sil.Var id_block, f, block_type), t, Sil.Var id, loc)) fields_ids in Sil.Set (Sil.Lfield (Sil.Var id_block, f, block_type), t, Sil.Var id, loc)) fields_ids in
@ -336,6 +337,7 @@ struct
let pln = trans_state.parent_line_number in let pln = trans_state.parent_line_number in
let sil_loc = CLocation.get_sil_location stmt_info pln context in let sil_loc = CLocation.get_sil_location stmt_info pln context in
let pvar = CVar_decl.sil_var_of_decl_ref context decl_ref procname in let pvar = CVar_decl.sil_var_of_decl_ref context decl_ref procname in
CContext.add_block_static_var context procname (pvar, typ);
let e = Sil.Lvar pvar in let e = Sil.Lvar pvar in
let exps = if Self.is_var_self pvar (CContext.is_objc_method context) then let exps = if Self.is_var_self pvar (CContext.is_objc_method context) then
let curr_class = CContext.get_curr_class context in let curr_class = CContext.get_curr_class context in
@ -1874,25 +1876,10 @@ struct
let loc = let loc =
(match stmt_info.Clang_ast_t.si_source_range with (l1, l2) -> (match stmt_info.Clang_ast_t.si_source_range with (l1, l2) ->
CLocation.clang_to_sil_location l1 pln (Some context.CContext.procdesc)) in CLocation.clang_to_sil_location l1 pln (Some context.CContext.procdesc)) in
(* Given a mangled name (possibly full) returns a plain mangled name *)
let ensure_plain_mangling m =
Mangled.from_string (Mangled.to_string m) in
(* Given a captured var, return the instruction to assign it to a temp *) (* Given a captured var, return the instruction to assign it to a temp *)
let assign_captured_var cv = let assign_captured_var (cvar, typ) =
let cvar, typ = (match cv with
| (cvar, typ, false) -> cvar, typ
| (cvar, typ, true) -> (* static case *)
let formals = Cfg.Procdesc.get_formals context.CContext.procdesc in
let cvar' = ensure_plain_mangling cvar in
(* we check if cvar' is a formal. In that case we need this plain mangled name *)
(* otherwise it's a static variable defined among the locals *)
(* and therefore we need the full mangled name *)
let cvar''=
if (IList.exists(fun (s, t) -> Mangled.from_string s = cvar') formals) then cvar'
else cvar in
(cvar'', typ)) in
let id = Ident.create_fresh Ident.knormal in let id = Ident.create_fresh Ident.knormal in
let instr = Sil.Letderef (id, Sil.Lvar (Sil.mk_pvar cvar procname), typ, loc) in let instr = Sil.Letderef (id, (Sil.Lvar cvar), typ, loc) in
(id, instr) in (id, instr) in
match decl with match decl with
| Clang_ast_t.BlockDecl (decl_info, block_decl_info) -> | Clang_ast_t.BlockDecl (decl_info, block_decl_info) ->
@ -1908,14 +1895,15 @@ struct
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
CContext.add_block context block_pname;
M.function_decl context.tenv context.cfg context.cg context.namespace decl (Some block_data); M.function_decl context.tenv context.cfg context.cg context.namespace decl (Some block_data);
Cfg.set_procname_priority context.cfg block_pname; Cfg.set_procname_priority context.cfg block_pname;
let captured_exps = IList.map (fun id -> Sil.Var id) ids in let captured_exps = IList.map (fun id -> Sil.Var id) ids in
let tu = Sil.Ctuple ((Sil.Const (Sil.Cfun block_pname)) :: captured_exps) in let tu = Sil.Ctuple ((Sil.Const (Sil.Cfun block_pname)) :: captured_exps) in
let block_name = Procname.to_string block_pname in let block_name = Procname.to_string block_pname in
let static_vars = CContext.static_vars_for_block context block_pname in
let captured_static_vars = captured_vars @ static_vars in
let alloc_block_instr, ids_block = let alloc_block_instr, ids_block =
allocate_block trans_state block_name captured_vars loc in allocate_block trans_state block_name captured_static_vars loc in
{ empty_res_trans with ids = ids_block @ ids; instrs = alloc_block_instr @ instrs; exps = [(Sil.Const tu, typ)]} { empty_res_trans with ids = ids_block @ ids; instrs = alloc_block_instr @ instrs; exps = [(Sil.Const tu, typ)]}
| _ -> assert false | _ -> assert false

@ -104,7 +104,7 @@ let captured_vars_from_block_info context cvl =
else else
let pvar = sil_var_of_decl_ref context dr procname in let pvar = sil_var_of_decl_ref context dr procname in
let typ = CTypes_decl.type_ptr_to_sil_type context.CContext.tenv type_ptr in let typ = CTypes_decl.type_ptr_to_sil_type context.CContext.tenv type_ptr in
(Sil.pvar_get_name pvar, typ, false) :: vars (pvar, typ) :: vars
| _ -> assert false) | _ -> assert false)
| _ -> assert false in | _ -> assert false in
IList.fold_right sil_var_of_captured_var cvl [] IList.fold_right sil_var_of_captured_var cvl []

@ -19,4 +19,4 @@ val add_var_to_locals : Cfg.Procdesc.t -> Clang_ast_t.decl -> Sil.typ -> Sil.pva
val compute_autorelease_pool_vars : CContext.t -> Clang_ast_t.stmt list -> (Sil.exp * Sil.typ) list val compute_autorelease_pool_vars : CContext.t -> Clang_ast_t.stmt list -> (Sil.exp * Sil.typ) list
val captured_vars_from_block_info : CContext.t -> Clang_ast_t.block_captured_variable list -> val captured_vars_from_block_info : CContext.t -> Clang_ast_t.block_captured_variable list ->
(Mangled.t * Sil.typ * bool) list (Sil.pvar * Sil.typ) list

@ -0,0 +1,49 @@
/*
* Copyright (c) 2015 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <Foundation/Foundation.h>
typedef void (^MyHandler) (NSString *name);
@interface C : NSObject
@property (nonatomic, strong) MyHandler handler;
@property (nonatomic, strong) NSString *name;
@property (nonatomic,strong) C *bla1;
@property (nonatomic,strong) C *bla2;
@end
@implementation C
- (void) foo {
static dispatch_once_t once;
static C* sharedInstance1;
dispatch_once(&once, ^{
sharedInstance1 = [[C alloc] init];
});
static C* sharedInstance2;
dispatch_once(&once, ^{
sharedInstance2 = [[C alloc] init];
});
_bla1 = sharedInstance1;
_bla2 = sharedInstance2;
sharedInstance2.handler = ^(NSString* s){
_name = sharedInstance2.name;
};
}
@end
int main() {
C *c = [[C alloc] init];
[c foo];
return 0;
}

@ -18,7 +18,7 @@ digraph iCFG {
21 -> 20 ; 21 -> 20 ;
20 [label="20: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_main1______2); [line 19]\n n$25=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_main1______2 ):unsigned long ) [line 19]\n *&__objc_anonymous_block_main1______2:class __objc_anonymous_block_main1______2 =n$25 [line 19]\n n$26=*&x:int [line 19]\n *n$25.x:int =n$26 [line 19]\n n$10=*&x:int [line 19]\n *&addblock:_fn_ (*)=(_fun___objc_anonymous_block_main1______2,n$10) [line 19]\n REMOVE_TEMPS(n$25,n$26,n$10); [line 19]\n " shape="box"] 20 [label="20: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_main1______2); [line 19]\n n$27=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_main1______2 ):unsigned long ) [line 19]\n *&__objc_anonymous_block_main1______2:class __objc_anonymous_block_main1______2 =n$27 [line 19]\n n$28=*&x:int [line 19]\n *n$27.x:int =n$28 [line 19]\n n$11=*&x:int [line 19]\n *&addblock:_fn_ (*)=(_fun___objc_anonymous_block_main1______2,n$11) [line 19]\n REMOVE_TEMPS(n$27,n$28,n$11); [line 19]\n " shape="box"]
20 -> 10 ; 20 -> 10 ;
@ -26,11 +26,11 @@ digraph iCFG {
19 -> 18 ; 19 -> 18 ;
18 [label="18: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block___objc_anonymous_block_main1______2______3); [line 25]\n n$22=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block___objc_anonymous_block_main1______2______3 ):unsigned long ) [line 25]\n *&__objc_anonymous_block___objc_anonymous_block_main1______2______3:class __objc_anonymous_block___objc_anonymous_block_main1______2______3 =n$22 [line 25]\n n$23=*&x:int [line 25]\n n$24=*&bla:int [line 25]\n *n$22.bla:int =n$23 [line 25]\n *n$22.x:int =n$24 [line 25]\n n$16=*&x:int [line 25]\n n$17=*&bla:int [line 25]\n *&addblock2:_fn_ (*)=(_fun___objc_anonymous_block___objc_anonymous_block_main1______2______3,n$16,n$17) [line 25]\n REMOVE_TEMPS(n$22,n$23,n$24,n$16,n$17); [line 25]\n " shape="box"] 18 [label="18: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block___objc_anonymous_block_main1______2______3); [line 25]\n n$23=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block___objc_anonymous_block_main1______2______3 ):unsigned long ) [line 25]\n *&__objc_anonymous_block___objc_anonymous_block_main1______2______3:class __objc_anonymous_block___objc_anonymous_block_main1______2______3 =n$23 [line 25]\n n$24=*&x:int [line 25]\n n$25=*&bla:int [line 25]\n n$26=*&#GB$main1_s:int [line 25]\n *n$23.bla:int =n$24 [line 25]\n *n$23.main1_s:int =n$25 [line 25]\n *n$23.x:int =n$26 [line 25]\n n$17=*&x:int [line 25]\n n$18=*&bla:int [line 25]\n *&addblock2:_fn_ (*)=(_fun___objc_anonymous_block___objc_anonymous_block_main1______2______3,n$17,n$18) [line 25]\n REMOVE_TEMPS(n$23,n$24,n$25,n$26,n$17,n$18); [line 25]\n " shape="box"]
18 -> 14 ; 18 -> 14 ;
17 [label="17: Return Stmt \n n$18=*&z:int [line 26]\n n$19=*&#GB$main1_s:int [line 26]\n n$20=*&x:int [line 26]\n n$21=*&bla:int [line 26]\n *&return:int =(((n$18 + n$19) + n$20) + n$21) [line 26]\n REMOVE_TEMPS(n$18,n$19,n$20,n$21); [line 26]\n NULLIFY(&z,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"] 17 [label="17: Return Stmt \n n$19=*&z:int [line 26]\n n$20=*&#GB$main1_s:int [line 26]\n n$21=*&x:int [line 26]\n n$22=*&bla:int [line 26]\n *&return:int =(((n$19 + n$20) + n$21) + n$22) [line 26]\n REMOVE_TEMPS(n$19,n$20,n$21,n$22); [line 26]\n NULLIFY(&z,false); [line 26]\n APPLY_ABSTRACTION; [line 26]\n " shape="box"]
17 -> 16 ; 17 -> 16 ;
@ -41,11 +41,11 @@ digraph iCFG {
15 -> 17 ; 15 -> 17 ;
14 [label="14: BinaryOperatorStmt: Assign \n n$14=*&addblock2:_fn_ (*) [line 29]\n n$15=n$14(1:int ) [line 29]\n *&add2:int =n$15 [line 29]\n REMOVE_TEMPS(n$14,n$15); [line 29]\n NULLIFY(&addblock2,false); [line 29]\n " shape="box"] 14 [label="14: BinaryOperatorStmt: Assign \n n$15=*&addblock2:_fn_ (*) [line 29]\n n$16=n$15(1:int ) [line 29]\n *&add2:int =n$16 [line 29]\n REMOVE_TEMPS(n$15,n$16); [line 29]\n NULLIFY(&addblock2,false); [line 29]\n " shape="box"]
14 -> 13 ; 14 -> 13 ;
13 [label="13: Return Stmt \n n$11=*&c:int [line 30]\n n$12=*&add2:int [line 30]\n n$13=*&bla:int [line 30]\n *&return:int =((n$11 + n$12) + n$13) [line 30]\n REMOVE_TEMPS(n$11,n$12,n$13); [line 30]\n NULLIFY(&__objc_anonymous_block___objc_anonymous_block_main1______2______3,true); [line 30]\n NULLIFY(&add2,false); [line 30]\n NULLIFY(&c,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"] 13 [label="13: Return Stmt \n n$12=*&c:int [line 30]\n n$13=*&add2:int [line 30]\n n$14=*&bla:int [line 30]\n *&return:int =((n$12 + n$13) + n$14) [line 30]\n REMOVE_TEMPS(n$12,n$13,n$14); [line 30]\n NULLIFY(&__objc_anonymous_block___objc_anonymous_block_main1______2______3,true); [line 30]\n NULLIFY(&add2,false); [line 30]\n NULLIFY(&c,false); [line 30]\n APPLY_ABSTRACTION; [line 30]\n " shape="box"]
13 -> 12 ; 13 -> 12 ;
@ -56,11 +56,11 @@ digraph iCFG {
11 -> 19 ; 11 -> 19 ;
10 [label="10: BinaryOperatorStmt: Assign \n n$8=*&addblock:_fn_ (*) [line 33]\n n$9=n$8(1:int ,2:int ) [line 33]\n *&add1:int =n$9 [line 33]\n REMOVE_TEMPS(n$8,n$9); [line 33]\n NULLIFY(&addblock,false); [line 33]\n " shape="box"] 10 [label="10: BinaryOperatorStmt: Assign \n n$9=*&addblock:_fn_ (*) [line 33]\n n$10=n$9(1:int ,2:int ) [line 33]\n *&add1:int =n$10 [line 33]\n REMOVE_TEMPS(n$9,n$10); [line 33]\n NULLIFY(&addblock,false); [line 33]\n " shape="box"]
10 -> 9 ; 10 -> 9 ;
9 [label="9: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_main1______1); [line 36]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_main1______1 ):unsigned long ) [line 36]\n *&__objc_anonymous_block_main1______1:class __objc_anonymous_block_main1______1 =n$7 [line 36]\n *&addblock:_fn_ (*)=(_fun___objc_anonymous_block_main1______1) [line 36]\n REMOVE_TEMPS(n$7); [line 36]\n " shape="box"] 9 [label="9: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_main1______1); [line 36]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_main1______1 ):unsigned long ) [line 36]\n *&__objc_anonymous_block_main1______1:class __objc_anonymous_block_main1______1 =n$7 [line 36]\n n$8=*&#GB$main1_s:int [line 36]\n *n$7.main1_s:int =n$8 [line 36]\n *&addblock:_fn_ (*)=(_fun___objc_anonymous_block_main1______1) [line 36]\n REMOVE_TEMPS(n$7,n$8); [line 36]\n " shape="box"]
9 -> 5 ; 9 -> 5 ;

@ -7,7 +7,7 @@ digraph iCFG {
15 -> 14 ; 15 -> 14 ;
14 [label="14: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_My_manager_m______1); [line 26]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_My_manager_m______1 ):unsigned long ) [line 26]\n *&__objc_anonymous_block_My_manager_m______1:class __objc_anonymous_block_My_manager_m______1 =n$7 [line 26]\n n$8=*&z:int [line 26]\n *n$7.z:int =n$8 [line 26]\n n$5=*&z:int [line 26]\n *&b:_fn_ (*)=(_fun___objc_anonymous_block_My_manager_m______1,n$5) [line 26]\n REMOVE_TEMPS(n$7,n$8,n$5); [line 26]\n " shape="box"] 14 [label="14: BinaryOperatorStmt: Assign \n DECLARE_LOCALS(&__objc_anonymous_block_My_manager_m______1); [line 26]\n n$7=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_My_manager_m______1 ):unsigned long ) [line 26]\n *&__objc_anonymous_block_My_manager_m______1:class __objc_anonymous_block_My_manager_m______1 =n$7 [line 26]\n n$8=*&z:int [line 26]\n n$9=*&#GB$g:int [line 26]\n *n$7.g:int =n$8 [line 26]\n *n$7.z:int =n$9 [line 26]\n n$5=*&z:int [line 26]\n *&b:_fn_ (*)=(_fun___objc_anonymous_block_My_manager_m______1,n$5) [line 26]\n REMOVE_TEMPS(n$7,n$8,n$9,n$5); [line 26]\n " shape="box"]
14 -> 10 ; 14 -> 10 ;

@ -39,7 +39,7 @@ digraph iCFG {
23 -> 32 ; 23 -> 32 ;
22 [label="22: BinaryOperatorStmt: Assign \n n$15=*&self:class A * [line 14]\n n$16=*&x:int [line 14]\n *n$15._x:int =n$16 [line 14]\n REMOVE_TEMPS(n$15,n$16); [line 14]\n NULLIFY(&self,false); [line 14]\n NULLIFY(&x,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] 22 [label="22: BinaryOperatorStmt: Assign \n n$17=*&self:class A * [line 14]\n n$18=*&x:int [line 14]\n *n$17._x:int =n$18 [line 14]\n REMOVE_TEMPS(n$17,n$18); [line 14]\n NULLIFY(&self,false); [line 14]\n NULLIFY(&x,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"]
22 -> 21 ; 22 -> 21 ;
@ -50,7 +50,7 @@ digraph iCFG {
20 -> 22 ; 20 -> 22 ;
19 [label="19: Return Stmt \n n$13=*&self:class A * [line 14]\n n$14=*n$13._x:int [line 14]\n *&return:int =n$14 [line 14]\n REMOVE_TEMPS(n$13,n$14); [line 14]\n NULLIFY(&self,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"] 19 [label="19: Return Stmt \n n$15=*&self:class A * [line 14]\n n$16=*n$15._x:int [line 14]\n *&return:int =n$16 [line 14]\n REMOVE_TEMPS(n$15,n$16); [line 14]\n NULLIFY(&self,false); [line 14]\n APPLY_ABSTRACTION; [line 14]\n " shape="box"]
19 -> 18 ; 19 -> 18 ;
@ -61,7 +61,7 @@ digraph iCFG {
17 -> 19 ; 17 -> 19 ;
16 [label="16: BinaryOperatorStmt: Assign \n n$11=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 37]\n n$9=_fun_A_init(n$11:class A *) virtual [line 37]\n *&#GB$A_trans_sharedInstance:struct objc_object *=n$9 [line 37]\n REMOVE_TEMPS(n$9,n$11); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] 16 [label="16: BinaryOperatorStmt: Assign \n n$12=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 37]\n n$10=_fun_A_init(n$12:class A *) virtual [line 37]\n *&#GB$A_trans_sharedInstance:struct objc_object *=n$10 [line 37]\n REMOVE_TEMPS(n$10,n$12); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"]
16 -> 15 ; 16 -> 15 ;
@ -72,15 +72,15 @@ digraph iCFG {
14 -> 16 ; 14 -> 16 ;
13 [label="13: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans______2); [line 36]\n n$12=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans______2 ):unsigned long ) [line 36]\n *&__objc_anonymous_block_A_trans______2:class __objc_anonymous_block_A_trans______2 =n$12 [line 36]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans______2) [line 36]\n REMOVE_TEMPS(n$12); [line 36]\n " shape="box"] 13 [label="13: DeclStmt \n DECLARE_LOCALS(&__objc_anonymous_block_A_trans______2); [line 36]\n n$13=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_trans______2 ):unsigned long ) [line 36]\n *&__objc_anonymous_block_A_trans______2:class __objc_anonymous_block_A_trans______2 =n$13 [line 36]\n n$14=*&#GB$A_trans_sharedInstance:struct objc_object * [line 36]\n *n$13.A_trans_sharedInstance:struct objc_object *=n$14 [line 36]\n *&dummy_block:_fn_ (*)=(_fun___objc_anonymous_block_A_trans______2) [line 36]\n REMOVE_TEMPS(n$13,n$14); [line 36]\n " shape="box"]
13 -> 12 ; 13 -> 12 ;
12 [label="12: Call n$8 \n n$8=*&dummy_block:_fn_ (*) [line 39]\n n$8() [line 39]\n REMOVE_TEMPS(n$8); [line 39]\n NULLIFY(&dummy_block,false); [line 39]\n " shape="box"] 12 [label="12: Call n$9 \n n$9=*&dummy_block:_fn_ (*) [line 39]\n n$9() [line 39]\n REMOVE_TEMPS(n$9); [line 39]\n NULLIFY(&dummy_block,false); [line 39]\n " shape="box"]
12 -> 11 ; 12 -> 11 ;
11 [label="11: Return Stmt \n n$7=*&#GB$A_trans_sharedInstance:struct objc_object * [line 40]\n *&return:struct objc_object *=n$7 [line 40]\n REMOVE_TEMPS(n$7); [line 40]\n NULLIFY(&__objc_anonymous_block_A_trans______2,true); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"] 11 [label="11: Return Stmt \n n$8=*&#GB$A_trans_sharedInstance:struct objc_object * [line 40]\n *&return:struct objc_object *=n$8 [line 40]\n REMOVE_TEMPS(n$8); [line 40]\n NULLIFY(&__objc_anonymous_block_A_trans______2,true); [line 40]\n APPLY_ABSTRACTION; [line 40]\n " shape="box"]
11 -> 10 ; 11 -> 10 ;
@ -102,7 +102,7 @@ digraph iCFG {
6 -> 8 ; 6 -> 8 ;
5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_sharedInstance______1); [line 29]\n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 27]\n n$6=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 27]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$6 [line 27]\n *&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*)=(_fun___objc_anonymous_block_A_sharedInstance______1) [line 29]\n REMOVE_TEMPS(n$6); [line 29]\n " shape="box"] 5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_sharedInstance______1); [line 29]\n DECLARE_LOCALS(&__objc_anonymous_block_A_sharedInstance______1); [line 27]\n n$6=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_sharedInstance______1 ):unsigned long ) [line 27]\n *&__objc_anonymous_block_A_sharedInstance______1:class __objc_anonymous_block_A_sharedInstance______1 =n$6 [line 27]\n n$7=*&#GB$A_sharedInstance_sharedInstance:struct objc_object * [line 27]\n *n$6.A_sharedInstance_sharedInstance:struct objc_object *=n$7 [line 27]\n *&infer___objc_anonymous_block_A_sharedInstance______1:_fn_ (*)=(_fun___objc_anonymous_block_A_sharedInstance______1) [line 29]\n REMOVE_TEMPS(n$6,n$7); [line 29]\n " shape="box"]
5 -> 4 ; 5 -> 4 ;

@ -3,11 +3,11 @@ digraph iCFG {
60 -> 55 ; 60 -> 55 ;
59 [label="59: BinaryOperatorStmt: Assign \n n$52=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 71]\n n$50=_fun_A_init(n$52:class A *) virtual [line 71]\n *&#GB$A_dispatch_barrier_example_a:class A *=n$50 [line 71]\n REMOVE_TEMPS(n$50,n$52); [line 71]\n " shape="box"] 59 [label="59: BinaryOperatorStmt: Assign \n n$57=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 71]\n n$55=_fun_A_init(n$57:class A *) virtual [line 71]\n *&#GB$A_dispatch_barrier_example_a:class A *=n$55 [line 71]\n REMOVE_TEMPS(n$55,n$57); [line 71]\n " shape="box"]
59 -> 58 ; 59 -> 58 ;
58 [label="58: BinaryOperatorStmt: Assign \n n$49=*&#GB$A_dispatch_barrier_example_a:class A * [line 72]\n *n$49.x:int =10 [line 72]\n REMOVE_TEMPS(n$49); [line 72]\n APPLY_ABSTRACTION; [line 72]\n " shape="box"] 58 [label="58: BinaryOperatorStmt: Assign \n n$54=*&#GB$A_dispatch_barrier_example_a:class A * [line 72]\n *n$54.x:int =10 [line 72]\n REMOVE_TEMPS(n$54); [line 72]\n APPLY_ABSTRACTION; [line 72]\n " shape="box"]
58 -> 57 ; 58 -> 57 ;
@ -18,15 +18,15 @@ digraph iCFG {
56 -> 59 ; 56 -> 59 ;
55 [label="55: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n n$53=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_barrier_example______6 ):unsigned long ) [line 70]\n *&__objc_anonymous_block_A_dispatch_barrier_example______6:class __objc_anonymous_block_A_dispatch_barrier_example______6 =n$53 [line 70]\n *&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_barrier_example______6) [line 70]\n REMOVE_TEMPS(n$53); [line 70]\n " shape="box"] 55 [label="55: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_barrier_example______6); [line 70]\n n$58=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_barrier_example______6 ):unsigned long ) [line 70]\n *&__objc_anonymous_block_A_dispatch_barrier_example______6:class __objc_anonymous_block_A_dispatch_barrier_example______6 =n$58 [line 70]\n n$59=*&#GB$A_dispatch_barrier_example_a:class A * [line 70]\n *n$58.A_dispatch_barrier_example_a:class A *=n$59 [line 70]\n *&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_barrier_example______6) [line 70]\n REMOVE_TEMPS(n$58,n$59); [line 70]\n " shape="box"]
55 -> 54 ; 55 -> 54 ;
54 [label="54: Call n$47 \n n$47=*&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*) [line 70]\n n$48=n$47() [line 70]\n REMOVE_TEMPS(n$47,n$48); [line 70]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 70]\n " shape="box"] 54 [label="54: Call n$52 \n n$52=*&infer___objc_anonymous_block_A_dispatch_barrier_example______6:_fn_ (*) [line 70]\n n$53=n$52() [line 70]\n REMOVE_TEMPS(n$52,n$53); [line 70]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 70]\n " shape="box"]
54 -> 53 ; 54 -> 53 ;
53 [label="53: Return Stmt \n n$45=*&#GB$A_dispatch_barrier_example_a:class A * [line 74]\n n$46=*n$45.x:int [line 74]\n *&return:int =n$46 [line 74]\n REMOVE_TEMPS(n$45,n$46); [line 74]\n NULLIFY(&__objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 74]\n APPLY_ABSTRACTION; [line 74]\n " shape="box"] 53 [label="53: Return Stmt \n n$50=*&#GB$A_dispatch_barrier_example_a:class A * [line 74]\n n$51=*n$50.x:int [line 74]\n *&return:int =n$51 [line 74]\n REMOVE_TEMPS(n$50,n$51); [line 74]\n NULLIFY(&__objc_anonymous_block_A_dispatch_barrier_example______6,true); [line 74]\n APPLY_ABSTRACTION; [line 74]\n " shape="box"]
53 -> 52 ; 53 -> 52 ;
@ -41,11 +41,11 @@ digraph iCFG {
50 -> 45 ; 50 -> 45 ;
49 [label="49: BinaryOperatorStmt: Assign \n n$43=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 62]\n n$41=_fun_A_init(n$43:class A *) virtual [line 62]\n *&#GB$A_dispatch_group_notify_example_a:class A *=n$41 [line 62]\n REMOVE_TEMPS(n$41,n$43); [line 62]\n " shape="box"] 49 [label="49: BinaryOperatorStmt: Assign \n n$47=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 62]\n n$45=_fun_A_init(n$47:class A *) virtual [line 62]\n *&#GB$A_dispatch_group_notify_example_a:class A *=n$45 [line 62]\n REMOVE_TEMPS(n$45,n$47); [line 62]\n " shape="box"]
49 -> 48 ; 49 -> 48 ;
48 [label="48: BinaryOperatorStmt: Assign \n n$40=*&#GB$A_dispatch_group_notify_example_a:class A * [line 63]\n *n$40.x:int =10 [line 63]\n REMOVE_TEMPS(n$40); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"] 48 [label="48: BinaryOperatorStmt: Assign \n n$44=*&#GB$A_dispatch_group_notify_example_a:class A * [line 63]\n *n$44.x:int =10 [line 63]\n REMOVE_TEMPS(n$44); [line 63]\n APPLY_ABSTRACTION; [line 63]\n " shape="box"]
48 -> 47 ; 48 -> 47 ;
@ -56,15 +56,15 @@ digraph iCFG {
46 -> 49 ; 46 -> 49 ;
45 [label="45: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n n$44=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_notify_example______5 ):unsigned long ) [line 61]\n *&__objc_anonymous_block_A_dispatch_group_notify_example______5:class __objc_anonymous_block_A_dispatch_group_notify_example______5 =n$44 [line 61]\n *&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_notify_example______5) [line 61]\n REMOVE_TEMPS(n$44); [line 61]\n " shape="box"] 45 [label="45: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_notify_example______5); [line 61]\n n$48=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_notify_example______5 ):unsigned long ) [line 61]\n *&__objc_anonymous_block_A_dispatch_group_notify_example______5:class __objc_anonymous_block_A_dispatch_group_notify_example______5 =n$48 [line 61]\n n$49=*&#GB$A_dispatch_group_notify_example_a:class A * [line 61]\n *n$48.A_dispatch_group_notify_example_a:class A *=n$49 [line 61]\n *&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_notify_example______5) [line 61]\n REMOVE_TEMPS(n$48,n$49); [line 61]\n " shape="box"]
45 -> 44 ; 45 -> 44 ;
44 [label="44: Call n$38 \n n$38=*&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*) [line 61]\n n$39=n$38() [line 61]\n REMOVE_TEMPS(n$38,n$39); [line 61]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 61]\n " shape="box"] 44 [label="44: Call n$42 \n n$42=*&infer___objc_anonymous_block_A_dispatch_group_notify_example______5:_fn_ (*) [line 61]\n n$43=n$42() [line 61]\n REMOVE_TEMPS(n$42,n$43); [line 61]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 61]\n " shape="box"]
44 -> 43 ; 44 -> 43 ;
43 [label="43: Return Stmt \n n$36=*&#GB$A_dispatch_group_notify_example_a:class A * [line 65]\n n$37=*n$36.x:int [line 65]\n *&return:int =n$37 [line 65]\n REMOVE_TEMPS(n$36,n$37); [line 65]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"] 43 [label="43: Return Stmt \n n$40=*&#GB$A_dispatch_group_notify_example_a:class A * [line 65]\n n$41=*n$40.x:int [line 65]\n *&return:int =n$41 [line 65]\n REMOVE_TEMPS(n$40,n$41); [line 65]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_notify_example______5,true); [line 65]\n APPLY_ABSTRACTION; [line 65]\n " shape="box"]
43 -> 42 ; 43 -> 42 ;
@ -79,11 +79,11 @@ digraph iCFG {
40 -> 35 ; 40 -> 35 ;
39 [label="39: BinaryOperatorStmt: Assign \n n$34=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 53]\n n$32=_fun_A_init(n$34:class A *) virtual [line 53]\n *&#GB$A_dispatch_group_example_a:class A *=n$32 [line 53]\n REMOVE_TEMPS(n$32,n$34); [line 53]\n " shape="box"] 39 [label="39: BinaryOperatorStmt: Assign \n n$37=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 53]\n n$35=_fun_A_init(n$37:class A *) virtual [line 53]\n *&#GB$A_dispatch_group_example_a:class A *=n$35 [line 53]\n REMOVE_TEMPS(n$35,n$37); [line 53]\n " shape="box"]
39 -> 38 ; 39 -> 38 ;
38 [label="38: BinaryOperatorStmt: Assign \n n$31=*&#GB$A_dispatch_group_example_a:class A * [line 54]\n *n$31.x:int =10 [line 54]\n REMOVE_TEMPS(n$31); [line 54]\n APPLY_ABSTRACTION; [line 54]\n " shape="box"] 38 [label="38: BinaryOperatorStmt: Assign \n n$34=*&#GB$A_dispatch_group_example_a:class A * [line 54]\n *n$34.x:int =10 [line 54]\n REMOVE_TEMPS(n$34); [line 54]\n APPLY_ABSTRACTION; [line 54]\n " shape="box"]
38 -> 37 ; 38 -> 37 ;
@ -94,15 +94,15 @@ digraph iCFG {
36 -> 39 ; 36 -> 39 ;
35 [label="35: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n n$35=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_example______4 ):unsigned long ) [line 52]\n *&__objc_anonymous_block_A_dispatch_group_example______4:class __objc_anonymous_block_A_dispatch_group_example______4 =n$35 [line 52]\n *&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_example______4) [line 52]\n REMOVE_TEMPS(n$35); [line 52]\n " shape="box"] 35 [label="35: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_group_example______4); [line 52]\n n$38=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_group_example______4 ):unsigned long ) [line 52]\n *&__objc_anonymous_block_A_dispatch_group_example______4:class __objc_anonymous_block_A_dispatch_group_example______4 =n$38 [line 52]\n n$39=*&#GB$A_dispatch_group_example_a:class A * [line 52]\n *n$38.A_dispatch_group_example_a:class A *=n$39 [line 52]\n *&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_group_example______4) [line 52]\n REMOVE_TEMPS(n$38,n$39); [line 52]\n " shape="box"]
35 -> 34 ; 35 -> 34 ;
34 [label="34: Call n$29 \n n$29=*&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*) [line 52]\n n$30=n$29() [line 52]\n REMOVE_TEMPS(n$29,n$30); [line 52]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_example______4,true); [line 52]\n " shape="box"] 34 [label="34: Call n$32 \n n$32=*&infer___objc_anonymous_block_A_dispatch_group_example______4:_fn_ (*) [line 52]\n n$33=n$32() [line 52]\n REMOVE_TEMPS(n$32,n$33); [line 52]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_group_example______4,true); [line 52]\n " shape="box"]
34 -> 33 ; 34 -> 33 ;
33 [label="33: Return Stmt \n n$27=*&#GB$A_dispatch_group_example_a:class A * [line 56]\n n$28=*n$27.x:int [line 56]\n *&return:int =n$28 [line 56]\n REMOVE_TEMPS(n$27,n$28); [line 56]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_example______4,true); [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"] 33 [label="33: Return Stmt \n n$30=*&#GB$A_dispatch_group_example_a:class A * [line 56]\n n$31=*n$30.x:int [line 56]\n *&return:int =n$31 [line 56]\n REMOVE_TEMPS(n$30,n$31); [line 56]\n NULLIFY(&__objc_anonymous_block_A_dispatch_group_example______4,true); [line 56]\n APPLY_ABSTRACTION; [line 56]\n " shape="box"]
33 -> 32 ; 33 -> 32 ;
@ -117,11 +117,11 @@ digraph iCFG {
30 -> 25 ; 30 -> 25 ;
29 [label="29: BinaryOperatorStmt: Assign \n n$25=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 44]\n n$23=_fun_A_init(n$25:class A *) virtual [line 44]\n *&#GB$A_dispatch_after_example_a:class A *=n$23 [line 44]\n REMOVE_TEMPS(n$23,n$25); [line 44]\n " shape="box"] 29 [label="29: BinaryOperatorStmt: Assign \n n$27=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 44]\n n$25=_fun_A_init(n$27:class A *) virtual [line 44]\n *&#GB$A_dispatch_after_example_a:class A *=n$25 [line 44]\n REMOVE_TEMPS(n$25,n$27); [line 44]\n " shape="box"]
29 -> 28 ; 29 -> 28 ;
28 [label="28: BinaryOperatorStmt: Assign \n n$22=*&#GB$A_dispatch_after_example_a:class A * [line 45]\n *n$22.x:int =10 [line 45]\n REMOVE_TEMPS(n$22); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"] 28 [label="28: BinaryOperatorStmt: Assign \n n$24=*&#GB$A_dispatch_after_example_a:class A * [line 45]\n *n$24.x:int =10 [line 45]\n REMOVE_TEMPS(n$24); [line 45]\n APPLY_ABSTRACTION; [line 45]\n " shape="box"]
28 -> 27 ; 28 -> 27 ;
@ -132,15 +132,15 @@ digraph iCFG {
26 -> 29 ; 26 -> 29 ;
25 [label="25: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_after_example______3); [line 42]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_after_example______3); [line 43]\n n$26=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_after_example______3 ):unsigned long ) [line 43]\n *&__objc_anonymous_block_A_dispatch_after_example______3:class __objc_anonymous_block_A_dispatch_after_example______3 =n$26 [line 43]\n *&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_after_example______3) [line 42]\n REMOVE_TEMPS(n$26); [line 42]\n " shape="box"] 25 [label="25: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_after_example______3); [line 42]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_after_example______3); [line 43]\n n$28=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_after_example______3 ):unsigned long ) [line 43]\n *&__objc_anonymous_block_A_dispatch_after_example______3:class __objc_anonymous_block_A_dispatch_after_example______3 =n$28 [line 43]\n n$29=*&#GB$A_dispatch_after_example_a:class A * [line 43]\n *n$28.A_dispatch_after_example_a:class A *=n$29 [line 43]\n *&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_after_example______3) [line 42]\n REMOVE_TEMPS(n$28,n$29); [line 42]\n " shape="box"]
25 -> 24 ; 25 -> 24 ;
24 [label="24: Call n$20 \n n$20=*&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*) [line 42]\n n$21=n$20() [line 42]\n REMOVE_TEMPS(n$20,n$21); [line 42]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_after_example______3,true); [line 42]\n " shape="box"] 24 [label="24: Call n$22 \n n$22=*&infer___objc_anonymous_block_A_dispatch_after_example______3:_fn_ (*) [line 42]\n n$23=n$22() [line 42]\n REMOVE_TEMPS(n$22,n$23); [line 42]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_after_example______3,true); [line 42]\n " shape="box"]
24 -> 23 ; 24 -> 23 ;
23 [label="23: Return Stmt \n n$18=*&#GB$A_dispatch_after_example_a:class A * [line 47]\n n$19=*n$18.x:int [line 47]\n *&return:int =n$19 [line 47]\n REMOVE_TEMPS(n$18,n$19); [line 47]\n NULLIFY(&__objc_anonymous_block_A_dispatch_after_example______3,true); [line 47]\n APPLY_ABSTRACTION; [line 47]\n " shape="box"] 23 [label="23: Return Stmt \n n$20=*&#GB$A_dispatch_after_example_a:class A * [line 47]\n n$21=*n$20.x:int [line 47]\n *&return:int =n$21 [line 47]\n REMOVE_TEMPS(n$20,n$21); [line 47]\n NULLIFY(&__objc_anonymous_block_A_dispatch_after_example______3,true); [line 47]\n APPLY_ABSTRACTION; [line 47]\n " shape="box"]
23 -> 22 ; 23 -> 22 ;
@ -155,11 +155,11 @@ digraph iCFG {
20 -> 15 ; 20 -> 15 ;
19 [label="19: BinaryOperatorStmt: Assign \n n$16=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 34]\n n$14=_fun_A_init(n$16:class A *) virtual [line 34]\n *&#GB$A_dispatch_async_example_a:class A *=n$14 [line 34]\n REMOVE_TEMPS(n$14,n$16); [line 34]\n " shape="box"] 19 [label="19: BinaryOperatorStmt: Assign \n n$17=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 34]\n n$15=_fun_A_init(n$17:class A *) virtual [line 34]\n *&#GB$A_dispatch_async_example_a:class A *=n$15 [line 34]\n REMOVE_TEMPS(n$15,n$17); [line 34]\n " shape="box"]
19 -> 18 ; 19 -> 18 ;
18 [label="18: BinaryOperatorStmt: Assign \n n$13=*&#GB$A_dispatch_async_example_a:class A * [line 35]\n *n$13.x:int =10 [line 35]\n REMOVE_TEMPS(n$13); [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"] 18 [label="18: BinaryOperatorStmt: Assign \n n$14=*&#GB$A_dispatch_async_example_a:class A * [line 35]\n *n$14.x:int =10 [line 35]\n REMOVE_TEMPS(n$14); [line 35]\n APPLY_ABSTRACTION; [line 35]\n " shape="box"]
18 -> 17 ; 18 -> 17 ;
@ -170,15 +170,15 @@ digraph iCFG {
16 -> 19 ; 16 -> 19 ;
15 [label="15: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n n$17=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_async_example______2 ):unsigned long ) [line 33]\n *&__objc_anonymous_block_A_dispatch_async_example______2:class __objc_anonymous_block_A_dispatch_async_example______2 =n$17 [line 33]\n *&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_async_example______2) [line 33]\n REMOVE_TEMPS(n$17); [line 33]\n " shape="box"] 15 [label="15: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_async_example______2); [line 33]\n n$18=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_async_example______2 ):unsigned long ) [line 33]\n *&__objc_anonymous_block_A_dispatch_async_example______2:class __objc_anonymous_block_A_dispatch_async_example______2 =n$18 [line 33]\n n$19=*&#GB$A_dispatch_async_example_a:class A * [line 33]\n *n$18.A_dispatch_async_example_a:class A *=n$19 [line 33]\n *&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_async_example______2) [line 33]\n REMOVE_TEMPS(n$18,n$19); [line 33]\n " shape="box"]
15 -> 14 ; 15 -> 14 ;
14 [label="14: Call n$11 \n n$11=*&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*) [line 33]\n n$12=n$11() [line 33]\n REMOVE_TEMPS(n$11,n$12); [line 33]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_async_example______2,true); [line 33]\n " shape="box"] 14 [label="14: Call n$12 \n n$12=*&infer___objc_anonymous_block_A_dispatch_async_example______2:_fn_ (*) [line 33]\n n$13=n$12() [line 33]\n REMOVE_TEMPS(n$12,n$13); [line 33]\n NULLIFY(&infer___objc_anonymous_block_A_dispatch_async_example______2,true); [line 33]\n " shape="box"]
14 -> 13 ; 14 -> 13 ;
13 [label="13: Return Stmt \n n$9=*&#GB$A_dispatch_async_example_a:class A * [line 37]\n n$10=*n$9.x:int [line 37]\n *&return:int =n$10 [line 37]\n REMOVE_TEMPS(n$9,n$10); [line 37]\n NULLIFY(&__objc_anonymous_block_A_dispatch_async_example______2,true); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"] 13 [label="13: Return Stmt \n n$10=*&#GB$A_dispatch_async_example_a:class A * [line 37]\n n$11=*n$10.x:int [line 37]\n *&return:int =n$11 [line 37]\n REMOVE_TEMPS(n$10,n$11); [line 37]\n NULLIFY(&__objc_anonymous_block_A_dispatch_async_example______2,true); [line 37]\n APPLY_ABSTRACTION; [line 37]\n " shape="box"]
13 -> 12 ; 13 -> 12 ;
@ -208,7 +208,7 @@ digraph iCFG {
6 -> 9 ; 6 -> 9 ;
5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_once_example______1); [line 23]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_once_example______1); [line 24]\n n$8=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_once_example______1 ):unsigned long ) [line 24]\n *&__objc_anonymous_block_A_dispatch_once_example______1:class __objc_anonymous_block_A_dispatch_once_example______1 =n$8 [line 24]\n *&infer___objc_anonymous_block_A_dispatch_once_example______1:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_once_example______1) [line 23]\n REMOVE_TEMPS(n$8); [line 23]\n " shape="box"] 5 [label="5: DeclStmt \n DECLARE_LOCALS(&infer___objc_anonymous_block_A_dispatch_once_example______1); [line 23]\n DECLARE_LOCALS(&__objc_anonymous_block_A_dispatch_once_example______1); [line 24]\n n$8=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_dispatch_once_example______1 ):unsigned long ) [line 24]\n *&__objc_anonymous_block_A_dispatch_once_example______1:class __objc_anonymous_block_A_dispatch_once_example______1 =n$8 [line 24]\n n$9=*&#GB$A_dispatch_once_example_a:class A * [line 24]\n *n$8.A_dispatch_once_example_a:class A *=n$9 [line 24]\n *&infer___objc_anonymous_block_A_dispatch_once_example______1:_fn_ (*)=(_fun___objc_anonymous_block_A_dispatch_once_example______1) [line 23]\n REMOVE_TEMPS(n$8,n$9); [line 23]\n " shape="box"]
5 -> 4 ; 5 -> 4 ;

@ -10,11 +10,11 @@ digraph iCFG {
29 -> 31 ; 29 -> 31 ;
28 [label="28: Call (_fun___objc_anonymous_block_A_test3______4) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test3______4); [line 59]\n n$17=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test3______4 ):unsigned long ) [line 59]\n *&__objc_anonymous_block_A_test3______4:class __objc_anonymous_block_A_test3______4 =n$17 [line 59]\n (_fun___objc_anonymous_block_A_test3______4)() [line 59]\n REMOVE_TEMPS(n$17); [line 59]\n " shape="box"] 28 [label="28: Call (_fun___objc_anonymous_block_A_test3______4) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test3______4); [line 59]\n n$20=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test3______4 ):unsigned long ) [line 59]\n *&__objc_anonymous_block_A_test3______4:class __objc_anonymous_block_A_test3______4 =n$20 [line 59]\n n$21=*&#GB$A_test3_i:int [line 59]\n *n$20.A_test3_i:int =n$21 [line 59]\n (_fun___objc_anonymous_block_A_test3______4)() [line 59]\n REMOVE_TEMPS(n$20,n$21); [line 59]\n " shape="box"]
28 -> 24 ; 28 -> 24 ;
27 [label="27: UnaryOperator \n n$16=*&#GB$A_test3_i:int [line 61]\n *&#GB$A_test3_i:int =(n$16 + 1) [line 61]\n REMOVE_TEMPS(n$16); [line 61]\n APPLY_ABSTRACTION; [line 61]\n " shape="box"] 27 [label="27: UnaryOperator \n n$19=*&#GB$A_test3_i:int [line 61]\n *&#GB$A_test3_i:int =(n$19 + 1) [line 61]\n REMOVE_TEMPS(n$19); [line 61]\n APPLY_ABSTRACTION; [line 61]\n " shape="box"]
27 -> 26 ; 27 -> 26 ;
@ -25,7 +25,7 @@ digraph iCFG {
25 -> 27 ; 25 -> 27 ;
24 [label="24: Return Stmt \n n$15=*&#GB$A_test3_i:int [line 64]\n *&return:int =n$15 [line 64]\n REMOVE_TEMPS(n$15); [line 64]\n NULLIFY(&__objc_anonymous_block_A_test3______4,true); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"] 24 [label="24: Return Stmt \n n$18=*&#GB$A_test3_i:int [line 64]\n *&return:int =n$18 [line 64]\n REMOVE_TEMPS(n$18); [line 64]\n NULLIFY(&__objc_anonymous_block_A_test3______4,true); [line 64]\n APPLY_ABSTRACTION; [line 64]\n " shape="box"]
24 -> 23 ; 24 -> 23 ;
@ -36,15 +36,15 @@ digraph iCFG {
22 -> 28 ; 22 -> 28 ;
21 [label="21: BinaryOperatorStmt: Assign \n n$14=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 43]\n n$12=_fun_A_init(n$14:class A *) virtual [line 43]\n *&#GB$A_test2_sharedInstance:struct objc_object *=n$12 [line 43]\n REMOVE_TEMPS(n$12,n$14); [line 43]\n " shape="box"] 21 [label="21: BinaryOperatorStmt: Assign \n n$17=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 43]\n n$15=_fun_A_init(n$17:class A *) virtual [line 43]\n *&#GB$A_test2_sharedInstance:struct objc_object *=n$15 [line 43]\n REMOVE_TEMPS(n$15,n$17); [line 43]\n " shape="box"]
21 -> 20 ; 21 -> 20 ;
20 [label="20: Call (_fun___objc_anonymous_block_A_test2______3) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test2______3); [line 44]\n n$11=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test2______3 ):unsigned long ) [line 44]\n *&__objc_anonymous_block_A_test2______3:class __objc_anonymous_block_A_test2______3 =n$11 [line 44]\n (_fun___objc_anonymous_block_A_test2______3)() [line 44]\n REMOVE_TEMPS(n$11); [line 44]\n " shape="box"] 20 [label="20: Call (_fun___objc_anonymous_block_A_test2______3) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test2______3); [line 44]\n n$13=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test2______3 ):unsigned long ) [line 44]\n *&__objc_anonymous_block_A_test2______3:class __objc_anonymous_block_A_test2______3 =n$13 [line 44]\n n$14=*&#GB$A_test2_sharedInstance:struct objc_object * [line 44]\n *n$13.A_test2_sharedInstance:struct objc_object *=n$14 [line 44]\n (_fun___objc_anonymous_block_A_test2______3)() [line 44]\n REMOVE_TEMPS(n$13,n$14); [line 44]\n " shape="box"]
20 -> 16 ; 20 -> 16 ;
19 [label="19: DeclStmt \n n$10=*&#GB$A_test2_sharedInstance:struct objc_object * [line 46]\n *&p:struct objc_object *=n$10 [line 46]\n REMOVE_TEMPS(n$10); [line 46]\n NULLIFY(&p,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"] 19 [label="19: DeclStmt \n n$12=*&#GB$A_test2_sharedInstance:struct objc_object * [line 46]\n *&p:struct objc_object *=n$12 [line 46]\n REMOVE_TEMPS(n$12); [line 46]\n NULLIFY(&p,false); [line 46]\n APPLY_ABSTRACTION; [line 46]\n " shape="box"]
19 -> 18 ; 19 -> 18 ;
@ -55,7 +55,7 @@ digraph iCFG {
17 -> 19 ; 17 -> 19 ;
16 [label="16: Return Stmt \n n$9=*&#GB$A_test2_sharedInstance:struct objc_object * [line 49]\n *&return:struct objc_object *=n$9 [line 49]\n REMOVE_TEMPS(n$9); [line 49]\n NULLIFY(&__objc_anonymous_block_A_test2______3,true); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"] 16 [label="16: Return Stmt \n n$11=*&#GB$A_test2_sharedInstance:struct objc_object * [line 49]\n *&return:struct objc_object *=n$11 [line 49]\n REMOVE_TEMPS(n$11); [line 49]\n NULLIFY(&__objc_anonymous_block_A_test2______3,true); [line 49]\n APPLY_ABSTRACTION; [line 49]\n " shape="box"]
16 -> 15 ; 16 -> 15 ;
@ -66,11 +66,11 @@ digraph iCFG {
14 -> 21 ; 14 -> 21 ;
13 [label="13: Call (_fun___objc_anonymous_block_A_test_leak______2) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test_leak______2); [line 32]\n n$8=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test_leak______2 ):unsigned long ) [line 32]\n *&__objc_anonymous_block_A_test_leak______2:class __objc_anonymous_block_A_test_leak______2 =n$8 [line 32]\n (_fun___objc_anonymous_block_A_test_leak______2)() [line 32]\n REMOVE_TEMPS(n$8); [line 32]\n NULLIFY(&__objc_anonymous_block_A_test_leak______2,true); [line 32]\n APPLY_ABSTRACTION; [line 32]\n " shape="box"] 13 [label="13: Call (_fun___objc_anonymous_block_A_test_leak______2) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test_leak______2); [line 32]\n n$9=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test_leak______2 ):unsigned long ) [line 32]\n *&__objc_anonymous_block_A_test_leak______2:class __objc_anonymous_block_A_test_leak______2 =n$9 [line 32]\n n$10=*&#GB$A_test_leak_sharedInstance:struct objc_object * [line 32]\n *n$9.A_test_leak_sharedInstance:struct objc_object *=n$10 [line 32]\n (_fun___objc_anonymous_block_A_test_leak______2)() [line 32]\n REMOVE_TEMPS(n$9,n$10); [line 32]\n NULLIFY(&__objc_anonymous_block_A_test_leak______2,true); [line 32]\n APPLY_ABSTRACTION; [line 32]\n " shape="box"]
13 -> 9 ; 13 -> 9 ;
12 [label="12: BinaryOperatorStmt: Assign \n n$7=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 33]\n n$5=_fun_A_init(n$7:class A *) virtual [line 33]\n *&#GB$A_test_leak_sharedInstance:struct objc_object *=n$5 [line 33]\n REMOVE_TEMPS(n$5,n$7); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"] 12 [label="12: BinaryOperatorStmt: Assign \n n$8=_fun___objc_alloc_no_fail(sizeof(class A ):unsigned long ) [line 33]\n n$6=_fun_A_init(n$8:class A *) virtual [line 33]\n *&#GB$A_test_leak_sharedInstance:struct objc_object *=n$6 [line 33]\n REMOVE_TEMPS(n$6,n$8); [line 33]\n APPLY_ABSTRACTION; [line 33]\n " shape="box"]
12 -> 11 ; 12 -> 11 ;
@ -88,7 +88,7 @@ digraph iCFG {
8 -> 13 ; 8 -> 13 ;
7 [label="7: Call (_fun___objc_anonymous_block_A_test______1) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test______1); [line 21]\n n$4=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test______1 ):unsigned long ) [line 21]\n *&__objc_anonymous_block_A_test______1:class __objc_anonymous_block_A_test______1 =n$4 [line 21]\n (_fun___objc_anonymous_block_A_test______1)() [line 21]\n REMOVE_TEMPS(n$4); [line 21]\n " shape="box"] 7 [label="7: Call (_fun___objc_anonymous_block_A_test______1) \n DECLARE_LOCALS(&__objc_anonymous_block_A_test______1); [line 21]\n n$4=_fun___objc_alloc_no_fail(sizeof(class __objc_anonymous_block_A_test______1 ):unsigned long ) [line 21]\n *&__objc_anonymous_block_A_test______1:class __objc_anonymous_block_A_test______1 =n$4 [line 21]\n n$5=*&#GB$A_test_sharedInstance:struct objc_object * [line 21]\n *n$4.A_test_sharedInstance:struct objc_object *=n$5 [line 21]\n (_fun___objc_anonymous_block_A_test______1)() [line 21]\n REMOVE_TEMPS(n$4,n$5); [line 21]\n " shape="box"]
7 -> 3 ; 7 -> 3 ;

@ -0,0 +1,65 @@
/*
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package endtoend.objc;
import static org.hamcrest.MatcherAssert.assertThat;
import static utils.matchers.ResultContainsErrorInMethod.contains;
import static utils.matchers.ResultContainsExactly.containsExactly;
import static utils.matchers.ResultContainsNoErrorInMethod.doesNotContain;
import com.google.common.collect.ImmutableList;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import java.io.IOException;
import utils.DebuggableTemporaryFolder;
import utils.InferException;
import utils.InferResults;
import utils.InferRunner;
public class RetainCycleStaticVarTest {
public static final String FILE =
"infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleStaticVar.m";
private static ImmutableList<String> inferCmd;
public static final String RETAIN_CYCLE = "RETAIN_CYCLE";
@ClassRule
public static DebuggableTemporaryFolder folder =
new DebuggableTemporaryFolder();
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommand(folder, FILE);
}
@Test
public void whenInferRunsOnStrongCycleThenRCIsFound()
throws InterruptedException, IOException, InferException {
InferResults inferResults = InferRunner.runInferObjC(inferCmd);
String[] procedures = {
"main",
};
assertThat(
"Results should contain the expected retain cycles",
inferResults,
containsExactly(
RETAIN_CYCLE,
FILE,
procedures
)
);
}
}
Loading…
Cancel
Save