From aae319376d9d94f417631c6d1a5612cc1cf58ac9 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Mon, 19 Feb 2018 05:47:07 -0800 Subject: [PATCH] [retain cycles] Fix renaming of closures, finds more retain cycles Reviewed By: ddino Differential Revision: D7012360 fbshipit-source-id: 4a972d3 --- infer/src/backend/RetainCycles.ml | 25 +++--- infer/src/backend/prop.ml | 7 +- .../codetoanalyze/objc/errors/issues.exp | 3 +- .../RetainCycleBlocks.m | 25 ++++++ .../objc/shared/block/block_release.m | 4 +- .../objc/shared/block/block_release.m.dot | 76 +++++++++---------- .../MemoryLeakExample.m | 2 +- .../MemoryLeakExample.m.dot | 40 +++++----- 8 files changed, 103 insertions(+), 79 deletions(-) diff --git a/infer/src/backend/RetainCycles.ml b/infer/src/backend/RetainCycles.ml index 0ecdbfac1..2c0b7ed1f 100644 --- a/infer/src/backend/RetainCycles.ml +++ b/infer/src/backend/RetainCycles.ml @@ -91,15 +91,16 @@ let edge_is_strong tenv obj_edge = let get_cycle_blocks root_node exp = match exp with | Exp.Closure {name; captured_vars} -> - List.find - ~f:(fun (e, _, typ) -> - match typ.Typ.desc with - | Typ.Tptr (_, Typ.Pk_objc_weak) | Typ.Tptr (_, Typ.Pk_objc_unsafe_unretained) -> - false - | _ -> - Exp.equal e root_node.RetainCyclesType.rc_node_exp ) - captured_vars - |> Option.map ~f:(fun (_, var, _) -> (name, var)) + if List.exists + ~f:(fun (e, _, typ) -> + match typ.Typ.desc with + | Typ.Tptr (_, Typ.Pk_objc_weak) | Typ.Tptr (_, Typ.Pk_objc_unsafe_unretained) -> + false + | _ -> + Exp.equal e root_node.RetainCyclesType.rc_node_exp ) + captured_vars + then Some name + else None | _ -> None @@ -132,11 +133,7 @@ let get_cycle root tenv prop = let cycle_block_opt = get_cycle_blocks root_node f_exp in (* cycle with a block *) if edge_is_strong tenv obj_edge && Option.is_some cycle_block_opt then - let procname, var = Option.value_exn cycle_block_opt in - (* From the captured variables we get the actual name of the variable - that is more useful for the error message *) - let updated_from_node = {from_node with rc_node_exp= Exp.Lvar var} in - let edge = Object {obj_edge with rc_from= updated_from_node} in + let procname = Option.value_exn cycle_block_opt in let edge2 = Block procname in (edge2 :: edge :: rev_path, true) else diff --git a/infer/src/backend/prop.ml b/infer/src/backend/prop.ml index fd71e8995..dcd190054 100644 --- a/infer/src/backend/prop.ml +++ b/infer/src/backend/prop.ml @@ -2070,8 +2070,11 @@ let rec exp_captured_ren ren (e: Exp.t) : Exp.t = Var (ident_captured_ren ren id) | Exn e -> Exn (exp_captured_ren ren e) - | Closure _ -> - e (* TODO: why captured vars not renamed? *) + | Closure {name; captured_vars} -> + let captured_vars' = + List.map ~f:(fun (e, v, t) -> (exp_captured_ren ren e, v, t)) captured_vars + in + Closure {name; captured_vars= captured_vars'} | Const _ -> e | Sizeof ({dynamic_length} as sizeof_data) -> diff --git a/infer/tests/codetoanalyze/objc/errors/issues.exp b/infer/tests/codetoanalyze/objc/errors/issues.exp index e9d5a52be..72312fd89 100644 --- a/infer/tests/codetoanalyze/objc/errors/issues.exp +++ b/infer/tests/codetoanalyze/objc/errors/issues.exp @@ -20,7 +20,6 @@ codetoanalyze/objc/shared/block/BlockVar.m, BlockVar_capturedNullDeref, 5, NULL_ codetoanalyze/objc/shared/block/BlockVar.m, BlockVar_navigateToURLInBackground, 8, NULL_DEREFERENCE, [start of procedure navigateToURLInBackground,start of procedure block,start of procedure test,return from a call to BlockVar_test,return from a call to objc_blockBlockVar_navigateToURLInBackground_1,Condition is true] codetoanalyze/objc/shared/block/block.m, main1, 31, DIVIDE_BY_ZERO, [start of procedure main1(),start of procedure block,start of procedure block,return from a call to objc_blockobjc_blockmain1_2_3,return from a call to objc_blockmain1_2,start of procedure block,return from a call to objc_blockmain1_1] codetoanalyze/objc/shared/block/block_no_args.m, My_manager_m, 10, NULL_DEREFERENCE, [start of procedure m,start of procedure block,return from a call to objc_blockMy_manager_m_1,Condition is true] -codetoanalyze/objc/shared/block/block_release.m, My_manager_blockReleaseTODO, 9, MEMORY_LEAK, [start of procedure blockReleaseTODO] codetoanalyze/objc/shared/category_procdesc/main.c, CategoryProcdescMain, 3, MEMORY_LEAK, [start of procedure CategoryProcdescMain(),Skipping performDaysWork: function or method not found] codetoanalyze/objc/shared/field_superclass/SuperExample.m, ASuper_init, 2, NULL_DEREFERENCE, [start of procedure init,start of procedure init,return from a call to BSuper_init] codetoanalyze/objc/errors/blocks_in_heap/BlockInHeap.m, block_in_heap_executed_after_bi_abduction_ok_test, 3, NULL_DEREFERENCE, [start of procedure block_in_heap_executed_after_bi_abduction_ok_test(),start of procedure block_in_heap_executed_after_bi_abduction_ok_no_retain_cycle(),start of procedure assign_block_to_ivar,return from a call to BlockInHeap_assign_block_to_ivar,start of procedure block,return from a call to objc_blockBlockInHeap_assign_block_to_ivar_1,return from a call to block_in_heap_executed_after_bi_abduction_ok_no_retain_cycle,Condition is true] @@ -31,6 +30,7 @@ codetoanalyze/objc/errors/initialization/struct_initlistexpr.c, field_set_correc codetoanalyze/objc/errors/initialization/struct_initlistexpr.c, implicit_expr_set_correctly, 3, DIVIDE_BY_ZERO, [start of procedure implicit_expr_set_correctly()] codetoanalyze/objc/errors/initialization/struct_initlistexpr.c, point_coords_set_correctly, 2, DIVIDE_BY_ZERO, [start of procedure point_coords_set_correctly()] codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, call_retain_self_in_block_cycle, 2, RETAIN_CYCLE, [start of procedure call_retain_self_in_block_cycle(),start of procedure retain_self_in_block,return from a call to RCBlock_retain_self_in_block] +codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m, retain_a_in_block_cycle, 4, RETAIN_CYCLE, [start of procedure retain_a_in_block_cycle()] codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle.m, strongcycle, 6, RETAIN_CYCLE, [start of procedure strongcycle()] codetoanalyze/objc/errors/memory_leaks_benchmark/retain_cycle2.m, strongcycle2, 4, RETAIN_CYCLE, [start of procedure strongcycle2(),start of procedure init,return from a call to Parent_init,start of procedure init,return from a call to Child_init,start of procedure setChild:,return from a call to Parent_setChild:,start of procedure setParent:,return from a call to Child_setParent:] codetoanalyze/objc/errors/npe/UpdateDict.m, add_nil_in_dict, 10, NULL_DEREFERENCE, [start of procedure add_nil_in_dict(),Skipping dictionaryWithObjectsAndKeys:: function or method not found] @@ -91,7 +91,6 @@ codetoanalyze/objc/shared/annotations/nullable_annotations.m, npe_property_nulla codetoanalyze/objc/shared/annotations/nullable_annotations_fields.m, A_nullable_field, 3, NULL_DEREFERENCE, [start of procedure nullable_field,Skipping getA(): function or method not found] codetoanalyze/objc/shared/block/dispatch.m, DispatchA_dispatch_a_block_variable_from_macro_delivers_initialised_object, 3, DIVIDE_BY_ZERO, [start of procedure dispatch_a_block_variable_from_macro_delivers_initialised_object,start of procedure dispatch_a_block_variable_from_macro,Skipping _dispatch_once(): function or method not found,return from a call to DispatchA_dispatch_a_block_variable_from_macro] codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_blockCapturedVarLeak, 6, MEMORY_LEAK, [start of procedure blockCapturedVarLeak,start of procedure block,return from a call to objc_blockMemoryLeakExample_blockCapturedVarLeak_1] -codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_blockFreeNoLeakTODO, 8, MEMORY_LEAK, [start of procedure blockFreeNoLeakTODO,start of procedure block,return from a call to objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2] codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_createCloseCrossGlyph:, 2, MEMORY_LEAK, [start of procedure createCloseCrossGlyph:,Skipping CGRectGetHeight(): function or method not found] codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_measureFrameSizeForText, 1, MEMORY_LEAK, [start of procedure measureFrameSizeForText] codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m, MemoryLeakExample_regularLeak, 3, MEMORY_LEAK, [start of procedure regularLeak] diff --git a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m index c817e24a3..baf67c85c 100644 --- a/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m +++ b/infer/tests/codetoanalyze/objc/errors/memory_leaks_benchmark/RetainCycleBlocks.m @@ -12,16 +12,31 @@ typedef void (^MyHandler)(RCBlock* name); +@interface RCBlockAA : NSObject + +@property(nonatomic, strong) RCBlock* b; + +@property(nonatomic, strong) RCBlockAA* child; + +@end + +typedef void (^MyAHandler)(RCBlockAA* name); + @interface RCBlock : NSObject { RCBlock* child; } @property(nonatomic, strong) MyHandler handler; +@property(nonatomic, strong) MyAHandler a_handler; + @property(nonatomic, strong) RCBlock* child; @end +@implementation RCBlockAA +@end + @implementation RCBlock // This code can be executed and one can check that there's a cycle because @@ -58,3 +73,13 @@ int call_retain_weak_self_in_block_no_cycle() { [c retain_weak_self_in_block]; return 0; } + +int retain_a_in_block_cycle() { + RCBlockAA* a = [RCBlockAA new]; + RCBlock* b = [RCBlock new]; + a.b = b; + b.a_handler = ^(RCBlockAA* b) { + a.child = a; + }; + return 0; +} diff --git a/infer/tests/codetoanalyze/objc/shared/block/block_release.m b/infer/tests/codetoanalyze/objc/shared/block/block_release.m index ccaf983c7..c80e828ef 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/block_release.m +++ b/infer/tests/codetoanalyze/objc/shared/block/block_release.m @@ -17,7 +17,7 @@ @implementation My_manager -- (int)blockReleaseTODO { +- (int)blockReleaseNoLeak { void (^b)(int a); int z = 3; CGContextRef context = CGBitmapContextCreate(NULL, 0, 0, 8, 0, 0, 0); @@ -26,7 +26,7 @@ if (newImage) CGImageRelease(newImage); }; - b(z); // currently doesn't work due to PRECONDITION_NOT_MET here + b(z); if (context) CGContextRelease(context); return z; diff --git a/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot b/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot index f75c3b082..61162a9ff 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot @@ -1,79 +1,79 @@ /* @generated */ digraph cfg { -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_1" [label="1: Start My_manager_blockReleaseTODO\nFormals: self:My_manager*\nLocals: newImage:CGImage* context:CGContext* z:int b:_fn_(*) \n DECLARE_LOCALS(&return,&newImage,&context,&z,&b); [line 20, column 1]\n " color=yellow style=filled] +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_1" [label="1: Start My_manager_blockReleaseNoLeak\nFormals: self:My_manager*\nLocals: newImage:CGImage* context:CGContext* z:int b:_fn_(*) \n DECLARE_LOCALS(&return,&newImage,&context,&z,&b); [line 20, column 1]\n " color=yellow style=filled] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_1" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_12" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_2" [label="2: Exit My_manager_blockReleaseTODO \n " color=yellow style=filled] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_1" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_12" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_2" [label="2: Exit My_manager_blockReleaseNoLeak \n " color=yellow style=filled] -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_3" [label="3: Return Stmt \n n$0=*&z:int [line 32, column 10]\n *&return:int=n$0 [line 32, column 3]\n " shape="box"] +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_3" [label="3: Return Stmt \n n$0=*&z:int [line 32, column 10]\n *&return:int=n$0 [line 32, column 3]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_3" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_2" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_4" [label="4: + \n " ] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_3" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_2" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_4" [label="4: + \n " ] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_4" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_3" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_5" [label="5: Prune (true branch) \n n$1=*&context:CGContext* [line 30, column 7]\n PRUNE(n$1, true); [line 30, column 7]\n " shape="invhouse"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_4" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_3" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_5" [label="5: Prune (true branch) \n n$1=*&context:CGContext* [line 30, column 7]\n PRUNE(n$1, true); [line 30, column 7]\n " shape="invhouse"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_5" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_7" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_6" [label="6: Prune (false branch) \n n$1=*&context:CGContext* [line 30, column 7]\n PRUNE(!n$1, false); [line 30, column 7]\n " shape="invhouse"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_5" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_7" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_6" [label="6: Prune (false branch) \n n$1=*&context:CGContext* [line 30, column 7]\n PRUNE(!n$1, false); [line 30, column 7]\n " shape="invhouse"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_6" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_4" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_7" [label="7: Call _fun_CGContextRelease \n n$2=*&context:CGContext* [line 31, column 22]\n _fun_CGContextRelease(n$2:CGContext*) [line 31, column 5]\n " shape="box"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_6" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_4" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_7" [label="7: Call _fun_CGContextRelease \n n$2=*&context:CGContext* [line 31, column 22]\n _fun_CGContextRelease(n$2:CGContext*) [line 31, column 5]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_7" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_4" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_8" [label="8: Call n$3 \n n$3=*&b:_fn_(*) [line 29, column 3]\n n$4=*&z:int [line 29, column 5]\n n$3(n$4:int) [line 29, column 3]\n " shape="box"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_7" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_4" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" [label="8: Call n$3 \n n$3=*&b:_fn_(*) [line 29, column 3]\n n$4=*&z:int [line 29, column 5]\n n$3(n$4:int) [line 29, column 3]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_8" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_5" ; - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_8" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_6" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_9" [label="9: BinaryOperatorStmt: Assign \n n$5=*&newImage:CGImage* [line 25, column 7]\n *&b:_fn_(*)=(_fun_objc_blockMy_manager_blockReleaseTODO_1,(n$5 &newImage:CGImage*)) [line 25, column 3]\n " shape="box"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_5" ; + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_6" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_9" [label="9: BinaryOperatorStmt: Assign \n n$5=*&newImage:CGImage* [line 25, column 7]\n *&b:_fn_(*)=(_fun_objc_blockMy_manager_blockReleaseNoLeak_1,(n$5 &newImage:CGImage*)) [line 25, column 3]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_9" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_8" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_10" [label="10: DeclStmt \n n$8=*&context:CGContext* [line 24, column 52]\n n$9=_fun_CGBitmapContextCreateImage(n$8:CGContext*) [line 24, column 25]\n *&newImage:CGImage*=n$9 [line 24, column 3]\n " shape="box"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_9" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_10" [label="10: DeclStmt \n n$8=*&context:CGContext* [line 24, column 52]\n n$9=_fun_CGBitmapContextCreateImage(n$8:CGContext*) [line 24, column 25]\n *&newImage:CGImage*=n$9 [line 24, column 3]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_10" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_9" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_11" [label="11: DeclStmt \n n$10=_fun_CGBitmapContextCreate(null:void*,0:unsigned long,0:unsigned long,8:unsigned long,0:unsigned long,null:CGColorSpace*,0:unsigned int) [line 23, column 26]\n *&context:CGContext*=n$10 [line 23, column 3]\n " shape="box"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_10" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_9" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_11" [label="11: DeclStmt \n n$10=_fun_CGBitmapContextCreate(null:void*,0:unsigned long,0:unsigned long,8:unsigned long,0:unsigned long,null:CGColorSpace*,0:unsigned int) [line 23, column 26]\n *&context:CGContext*=n$10 [line 23, column 3]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_11" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_10" ; -"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_12" [label="12: DeclStmt \n *&z:int=3 [line 22, column 3]\n " shape="box"] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_11" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_10" ; +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_12" [label="12: DeclStmt \n *&z:int=3 [line 22, column 3]\n " shape="box"] - "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_12" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_11" ; -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_1" [label="1: Start objc_blockMy_manager_blockReleaseTODO_1\nFormals: newImage:CGImage* a:int\nLocals: \nCaptured: newImage:CGImage* \n DECLARE_LOCALS(&return); [line 25, column 7]\n " color=yellow style=filled] + "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_12" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_11" ; +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_1" [label="1: Start objc_blockMy_manager_blockReleaseNoLeak_1\nFormals: newImage:CGImage* a:int\nLocals: \nCaptured: newImage:CGImage* \n DECLARE_LOCALS(&return); [line 25, column 7]\n " color=yellow style=filled] - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_1" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_5" ; - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_1" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_6" ; -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_2" [label="2: Exit objc_blockMy_manager_blockReleaseTODO_1 \n " color=yellow style=filled] + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_1" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_5" ; + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_1" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_6" ; +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_2" [label="2: Exit objc_blockMy_manager_blockReleaseNoLeak_1 \n " color=yellow style=filled] -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_3" [label="3: + \n " ] +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_3" [label="3: + \n " ] - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_3" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_4" ; -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_4" [label="4: between_join_and_exit \n " shape="box"] + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_3" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_4" ; +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_4" [label="4: between_join_and_exit \n " shape="box"] - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_4" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_2" ; -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_5" [label="5: Prune (true branch) \n n$6=*&newImage:CGImage* [line 26, column 9]\n PRUNE(n$6, true); [line 26, column 9]\n " shape="invhouse"] + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_4" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_2" ; +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_5" [label="5: Prune (true branch) \n n$6=*&newImage:CGImage* [line 26, column 9]\n PRUNE(n$6, true); [line 26, column 9]\n " shape="invhouse"] - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_5" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_7" ; -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_6" [label="6: Prune (false branch) \n n$6=*&newImage:CGImage* [line 26, column 9]\n PRUNE(!n$6, false); [line 26, column 9]\n " shape="invhouse"] + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_5" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_7" ; +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_6" [label="6: Prune (false branch) \n n$6=*&newImage:CGImage* [line 26, column 9]\n PRUNE(!n$6, false); [line 26, column 9]\n " shape="invhouse"] - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_6" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_3" ; -"objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_7" [label="7: Call _fun_CGImageRelease \n n$7=*&newImage:CGImage* [line 27, column 22]\n _fun_CGImageRelease(n$7:CGImage*) [line 27, column 7]\n " shape="box"] + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_6" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_3" ; +"objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_7" [label="7: Call _fun_CGImageRelease \n n$7=*&newImage:CGImage* [line 27, column 22]\n _fun_CGImageRelease(n$7:CGImage*) [line 27, column 7]\n " shape="box"] - "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_7" -> "objc_blockMy_manager_blockReleaseTODO_1.196983209d147be0ee88d9c747994569_3" ; + "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_7" -> "objc_blockMy_manager_blockReleaseNoLeak_1.a1f2f2c370e78fee994cf9a9d53a7210_3" ; } diff --git a/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m b/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m index d1c0f09bb..4981fda6f 100644 --- a/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m +++ b/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m @@ -99,7 +99,7 @@ CGColorRef FBColorCreateWithGray(CGFloat gray, CGFloat a); return blk(); } -- (int)blockFreeNoLeakTODO { +- (int)blockFreeNoLeak { int* x = malloc(sizeof(int)); *x = 2; int (^blk)(void) = ^() { diff --git a/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m.dot b/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m.dot index 505ae4771..0d8e3fd19 100644 --- a/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/memory_leaks_benchmark/MemoryLeakExample.m.dot @@ -200,29 +200,29 @@ digraph cfg { "blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_6" -> "blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_5" ; -"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_1" [label="1: Start MemoryLeakExample_blockFreeNoLeakTODO\nFormals: self:MemoryLeakExample*\nLocals: blk:_fn_(*) x:int* \n DECLARE_LOCALS(&return,&blk,&x); [line 102, column 1]\n " color=yellow style=filled] +"blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_1" [label="1: Start MemoryLeakExample_blockFreeNoLeak\nFormals: self:MemoryLeakExample*\nLocals: blk:_fn_(*) x:int* \n DECLARE_LOCALS(&return,&blk,&x); [line 102, column 1]\n " color=yellow style=filled] - "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_1" -> "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_6" ; -"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_2" [label="2: Exit MemoryLeakExample_blockFreeNoLeakTODO \n " color=yellow style=filled] + "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_1" -> "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_6" ; +"blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_2" [label="2: Exit MemoryLeakExample_blockFreeNoLeak \n " color=yellow style=filled] -"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_3" [label="3: Return Stmt \n n$47=*&blk:_fn_(*) [line 110, column 10]\n n$48=n$47() [line 110, column 10]\n *&return:int=n$48 [line 110, column 3]\n " shape="box"] +"blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_3" [label="3: Return Stmt \n n$47=*&blk:_fn_(*) [line 110, column 10]\n n$48=n$47() [line 110, column 10]\n *&return:int=n$48 [line 110, column 3]\n " shape="box"] - "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_3" -> "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_2" ; -"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_4" [label="4: DeclStmt \n n$49=*&x:int* [line 105, column 22]\n *&blk:_fn_(*)=(_fun_objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2,(n$49 &x:int*)) [line 105, column 3]\n " shape="box"] + "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_3" -> "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_2" ; +"blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_4" [label="4: DeclStmt \n n$49=*&x:int* [line 105, column 22]\n *&blk:_fn_(*)=(_fun_objc_blockMemoryLeakExample_blockFreeNoLeak_2,(n$49 &x:int*)) [line 105, column 3]\n " shape="box"] - "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_4" -> "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_3" ; -"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_5" [label="5: BinaryOperatorStmt: Assign \n n$54=*&x:int* [line 104, column 4]\n *n$54:int=2 [line 104, column 3]\n " shape="box"] + "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_4" -> "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_3" ; +"blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_5" [label="5: BinaryOperatorStmt: Assign \n n$54=*&x:int* [line 104, column 4]\n *n$54:int=2 [line 104, column 3]\n " shape="box"] - "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_5" -> "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_4" ; -"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_6" [label="6: DeclStmt \n n$55=_fun_malloc_no_fail(sizeof(t=int;nbytes=4):int) [line 103, column 12]\n *&x:int*=n$55 [line 103, column 3]\n " shape="box"] + "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_5" -> "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_4" ; +"blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_6" [label="6: DeclStmt \n n$55=_fun_malloc_no_fail(sizeof(t=int;nbytes=4):int) [line 103, column 12]\n *&x:int*=n$55 [line 103, column 3]\n " shape="box"] - "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_6" -> "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_5" ; + "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_6" -> "blockFreeNoLeak#MemoryLeakExample#instance.6bcefe2afb9f172f8aadbab54d9bd144_5" ; "test1:#MemoryLeakExample#class.6a178021c88203c49ec4a36c5d873685_1" [label="1: Start MemoryLeakExample_test1:\nFormals: str:__CFAttributedString const *\nLocals: \n DECLARE_LOCALS(&return); [line 44, column 1]\n " color=yellow style=filled] @@ -245,25 +245,25 @@ digraph cfg { "test2:#MemoryLeakExample#class.4d854f1c80289cc8e5422233831af105_3" -> "test2:#MemoryLeakExample#class.4d854f1c80289cc8e5422233831af105_2" ; -"objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_1" [label="1: Start objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2\nFormals: x:int*\nLocals: i:int\nCaptured: x:int* \n DECLARE_LOCALS(&return,&i); [line 105, column 22]\n " color=yellow style=filled] +"objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_1" [label="1: Start objc_blockMemoryLeakExample_blockFreeNoLeak_2\nFormals: x:int*\nLocals: i:int\nCaptured: x:int* \n DECLARE_LOCALS(&return,&i); [line 105, column 22]\n " color=yellow style=filled] - "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_1" -> "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_5" ; -"objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_2" [label="2: Exit objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2 \n " color=yellow style=filled] + "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_1" -> "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_5" ; +"objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_2" [label="2: Exit objc_blockMemoryLeakExample_blockFreeNoLeak_2 \n " color=yellow style=filled] -"objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_3" [label="3: Return Stmt \n n$50=*&i:int [line 108, column 12]\n *&return:int=n$50 [line 108, column 5]\n " shape="box"] +"objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_3" [label="3: Return Stmt \n n$50=*&i:int [line 108, column 12]\n *&return:int=n$50 [line 108, column 5]\n " shape="box"] - "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_3" -> "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_2" ; -"objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_4" [label="4: Call _fun_free \n n$51=*&x:int* [line 107, column 10]\n _fun_free(n$51:void*) [line 107, column 5]\n " shape="box"] + "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_3" -> "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_2" ; +"objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_4" [label="4: Call _fun_free \n n$51=*&x:int* [line 107, column 10]\n _fun_free(n$51:void*) [line 107, column 5]\n " shape="box"] - "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_4" -> "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_3" ; -"objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_5" [label="5: DeclStmt \n n$52=*&x:int* [line 106, column 14]\n n$53=*n$52:int [line 106, column 13]\n *&i:int=n$53 [line 106, column 5]\n " shape="box"] + "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_4" -> "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_3" ; +"objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_5" [label="5: DeclStmt \n n$52=*&x:int* [line 106, column 14]\n n$53=*n$52:int [line 106, column 13]\n *&i:int=n$53 [line 106, column 5]\n " shape="box"] - "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_5" -> "objc_blockMemoryLeakExample_blockFreeNoLeakTODO_2.75d33bce4351c16a4939470302c57868_4" ; + "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_5" -> "objc_blockMemoryLeakExample_blockFreeNoLeak_2.1717186f4031a201971ac91124f16c98_4" ; "objc_blockMemoryLeakExample_blockCapturedVarLeak_1.b434313b336514058f60e55fc6a4a73f_1" [label="1: Start objc_blockMemoryLeakExample_blockCapturedVarLeak_1\nFormals: x:int*\nLocals: \nCaptured: x:int* \n DECLARE_LOCALS(&return); [line 96, column 22]\n " color=yellow style=filled]