[retain cycles] Do not report when the captured variable is weak

Reviewed By: mbouaziz

Differential Revision: D6912514

fbshipit-source-id: a30635c
master
Dulma Churchill 7 years ago committed by Facebook Github Bot
parent d61c4927c1
commit 91fbe68cc9

@ -254,12 +254,12 @@ let rec pp_ pe pp_t f e =
subtype
and pp_captured_var pe pp_t f (exp, var, _) =
and pp_captured_var pe pp_t f (exp, var, typ) =
match exp with
| Lvar evar when Pvar.equal var evar ->
F.fprintf f "%a" (Pvar.pp pe) var
| _ ->
F.fprintf f "(%a %a)" (pp_ pe pp_t) exp (Pvar.pp pe) var
F.fprintf f "(%a %a:%a)" (pp_ pe pp_t) exp (Pvar.pp pe) var (Typ.pp pe) typ
let pp_printenv pe pp_typ f e = pp_ pe (pp_typ pe) f e

@ -67,7 +67,14 @@ let get_cycle root prop =
| Exp.Closure {captured_vars}
(* will turn on in prod when false positives have been addressed *)
when Config.debug_exceptions ->
List.find ~f:(fun (e, _, _) -> Exp.equal e root_node.rc_node_exp) 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.rc_node_exp )
captured_vars
|> Option.map ~f:snd3
| _ ->
None

@ -30,7 +30,7 @@ codetoanalyze/objc/errors/field_superclass/SubtypingExample.m, subtyping_test, 0
codetoanalyze/objc/errors/initialization/struct_initlistexpr.c, field_set_correctly, 2, DIVIDE_BY_ZERO, [start of procedure field_set_correctly()]
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, main, 2, RETAIN_CYCLE, [start of procedure main(),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, 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/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]

@ -36,10 +36,25 @@ typedef void (^MyHandler)(RCBlock* name);
};
}
- (void)retain_weak_self_in_block {
__weak typeof(self) weak_self = self;
self.handler = ^(RCBlock* b) {
__strong typeof(self) strong_self = weak_self;
if (strong_self)
strong_self->_child = b;
};
}
@end
int main() {
int call_retain_self_in_block_cycle() {
RCBlock* c = [[RCBlock alloc] init];
[c retain_self_in_block];
return 0;
}
int call_retain_weak_self_in_block_no_cycle() {
RCBlock* c = [[RCBlock alloc] init];
[c retain_weak_self_in_block];
return 0;
}

@ -41,7 +41,7 @@ digraph cfg {
"capture#A#instance.d411336575e4bf632a1828f5f5979726_2" [label="2: Exit A_capture \n " color=yellow style=filled]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$0=*&self:A* [line 47, column 4]\n n$1=*n$0._b:B* [line 47, column 4]\n n$2=*&self:A* [line 47, column 16]\n _fun_B_sHandler:(n$1:B*,(_fun_objc_blockA_capture_1,(n$2 &self)):_fn_(*)) virtual block_params [line 47, column 3]\n " shape="box"]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$0=*&self:A* [line 47, column 4]\n n$1=*n$0._b:B* [line 47, column 4]\n n$2=*&self:A* [line 47, column 16]\n _fun_B_sHandler:(n$1:B*,(_fun_objc_blockA_capture_1,(n$2 &self:A*)):_fn_(*)) virtual block_params [line 47, column 3]\n " shape="box"]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" -> "capture#A#instance.d411336575e4bf632a1828f5f5979726_2" ;

@ -85,7 +85,7 @@ digraph cfg {
"blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_3" -> "blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_2" ;
"blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_4" [label="4: DeclStmt \n n$13=*&x:int* [line 33, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_blockPostBad_2,(n$13 &x)) [line 33, column 3]\n " shape="box"]
"blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_4" [label="4: DeclStmt \n n$13=*&x:int* [line 33, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_blockPostBad_2,(n$13 &x:int*)) [line 33, column 3]\n " shape="box"]
"blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_4" -> "blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_3" ;
@ -104,7 +104,7 @@ digraph cfg {
"blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_3" -> "blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_2" ;
"blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_4" [label="4: DeclStmt \n n$18=*&x:int* [line 42, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_blockPostOk_3,(n$18 &x)) [line 42, column 3]\n " shape="box"]
"blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_4" [label="4: DeclStmt \n n$18=*&x:int* [line 42, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_blockPostOk_3,(n$18 &x:int*)) [line 42, column 3]\n " shape="box"]
"blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_4" -> "blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_3" ;
@ -127,7 +127,7 @@ digraph cfg {
"capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_3" -> "capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_2" ;
"capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_4" [label="4: DeclStmt \n n$22=*&x:int* [line 50, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_capturedNullDeref_4,(n$22 &x)) [line 50, column 3]\n " shape="box"]
"capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_4" [label="4: DeclStmt \n n$22=*&x:int* [line 50, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_capturedNullDeref_4,(n$22 &x:int*)) [line 50, column 3]\n " shape="box"]
"capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_4" -> "capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_3" ;
@ -150,7 +150,7 @@ digraph cfg {
"capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_4" -> "capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_3" ;
"capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_5" [label="5: DeclStmt \n n$27=*&x:int* [line 59, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_capturedNoNullDeref_5,(n$27 &x)) [line 59, column 3]\n " shape="box"]
"capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_5" [label="5: DeclStmt \n n$27=*&x:int* [line 59, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar_capturedNoNullDeref_5,(n$27 &x:int*)) [line 59, column 3]\n " shape="box"]
"capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_5" -> "capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_4" ;

@ -11,7 +11,7 @@ digraph cfg {
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_2" ;
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$2=*&self:B* [line 25, column 10]\n n$3=*n$2.h:int [line 25, column 10]\n n$4=*&self:B* const [line 26, column 11]\n _fun_B_foo:and:(n$3:int,(_fun_objc_blockB_f_1,(n$4 &self)):_fn_(*)) block_params [line 25, column 3]\n " shape="box"]
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$2=*&self:B* [line 25, column 10]\n n$3=*n$2.h:int [line 25, column 10]\n n$4=*&self:B* const [line 26, column 11]\n _fun_B_foo:and:(n$3:int,(_fun_objc_blockB_f_1,(n$4 &self:B* const )):_fn_(*)) block_params [line 25, column 3]\n " shape="box"]
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" ;

@ -49,7 +49,7 @@ digraph cfg {
"main1.38f534a9576db7ec6ebcbca8c111f942_7" -> "main1.38f534a9576db7ec6ebcbca8c111f942_6" ;
"main1.38f534a9576db7ec6ebcbca8c111f942_8" [label="8: BinaryOperatorStmt: Assign \n n$9=*&x:int [line 18, column 14]\n *&addblock:_fn_(*)=(_fun_objc_blockmain1_2,(n$9 &x)) [line 18, column 3]\n " shape="box"]
"main1.38f534a9576db7ec6ebcbca8c111f942_8" [label="8: BinaryOperatorStmt: Assign \n n$9=*&x:int [line 18, column 14]\n *&addblock:_fn_(*)=(_fun_objc_blockmain1_2,(n$9 &x:int)) [line 18, column 3]\n " shape="box"]
"main1.38f534a9576db7ec6ebcbca8c111f942_8" -> "main1.38f534a9576db7ec6ebcbca8c111f942_7" ;
@ -76,7 +76,7 @@ digraph cfg {
"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_4" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_3" ;
"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" [label="5: BinaryOperatorStmt: Assign \n n$15=*&x:int [line 24, column 17]\n n$16=*&bla:int [line 24, column 17]\n *&addblock2:_fn_(*)=(_fun_objc_blockobjc_blockmain1_2_3,(n$15 &x),(n$16 &bla)) [line 24, column 5]\n " shape="box"]
"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" [label="5: BinaryOperatorStmt: Assign \n n$15=*&x:int [line 24, column 17]\n n$16=*&bla:int [line 24, column 17]\n *&addblock2:_fn_(*)=(_fun_objc_blockobjc_blockmain1_2_3,(n$15 &x:int),(n$16 &bla:int)) [line 24, column 5]\n " shape="box"]
"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_4" ;

@ -44,7 +44,7 @@ digraph cfg {
"m#My_manager#instance.e773f849d062cb9801497b62f5c98f5e_11" -> "m#My_manager#instance.e773f849d062cb9801497b62f5c98f5e_10" ;
"m#My_manager#instance.e773f849d062cb9801497b62f5c98f5e_12" [label="12: BinaryOperatorStmt: Assign \n n$5=*&z:int [line 25, column 7]\n *&b:_fn_(*)=(_fun_objc_blockMy_manager_m_1,(n$5 &z)) [line 25, column 3]\n " shape="box"]
"m#My_manager#instance.e773f849d062cb9801497b62f5c98f5e_12" [label="12: BinaryOperatorStmt: Assign \n n$5=*&z:int [line 25, column 7]\n *&b:_fn_(*)=(_fun_objc_blockMy_manager_m_1,(n$5 &z:int)) [line 25, column 3]\n " shape="box"]
"m#My_manager#instance.e773f849d062cb9801497b62f5c98f5e_12" -> "m#My_manager#instance.e773f849d062cb9801497b62f5c98f5e_11" ;

@ -32,7 +32,7 @@ digraph cfg {
"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)) [line 25, column 3]\n " shape="box"]
"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"]
"blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_9" -> "blockReleaseTODO#My_manager#instance.8c1d633cf596e86a307167d9425628a8_8" ;

@ -37,7 +37,7 @@ digraph cfg {
"block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_3" -> "block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_2" ;
"block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_4" [label="4: Call _fun__dispatch_once \n n$6=*&a:DispatchA* [line 39, column 24]\n _fun__dispatch_once(&#GB<codetoanalyze/objc/shared/block/dispatch.m>$DispatchA_block_attribute_once:long*,(_fun_objc_blockDispatchA_block_attribute_2,(n$6 &a)):_fn_(*)) block_params [line 39, column 3]\n " shape="box"]
"block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_4" [label="4: Call _fun__dispatch_once \n n$6=*&a:DispatchA* [line 39, column 24]\n _fun__dispatch_once(&#GB<codetoanalyze/objc/shared/block/dispatch.m>$DispatchA_block_attribute_once:long*,(_fun_objc_blockDispatchA_block_attribute_2,(n$6 &a:DispatchA*)):_fn_(*)) block_params [line 39, column 3]\n " shape="box"]
"block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_4" -> "block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_3" ;

@ -188,7 +188,7 @@ digraph cfg {
"blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_3" -> "blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_2" ;
"blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_4" [label="4: DeclStmt \n n$42=*&x:int* [line 96, column 22]\n *&blk:_fn_(*)=(_fun_objc_blockMemoryLeakExample_blockCapturedVarLeak_1,(n$42 &x)) [line 96, column 3]\n " shape="box"]
"blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_4" [label="4: DeclStmt \n n$42=*&x:int* [line 96, column 22]\n *&blk:_fn_(*)=(_fun_objc_blockMemoryLeakExample_blockCapturedVarLeak_1,(n$42 &x:int*)) [line 96, column 3]\n " shape="box"]
"blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_4" -> "blockCapturedVarLeak#MemoryLeakExample#instance.53bb018bc84d6a696dc756e20b5b3f52_3" ;
@ -211,7 +211,7 @@ digraph cfg {
"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)) [line 105, column 3]\n " shape="box"]
"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"]
"blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_4" -> "blockFreeNoLeakTODO#MemoryLeakExample#instance.745cca07ccdb517734d79c9d7a1eaed8_3" ;

Loading…
Cancel
Save