diff --git a/infer/src/checkers/SelfInBlock.ml b/infer/src/checkers/SelfInBlock.ml index 2825af5731..1750c1e151 100644 --- a/infer/src/checkers/SelfInBlock.ml +++ b/infer/src/checkers/SelfInBlock.ml @@ -360,6 +360,18 @@ module TransferFunctions = struct let pp_session_name _node fmt = F.pp_print_string fmt "SelfCapturedInBlock" + let is_objc_instance attributes_opt = + match attributes_opt with + | Some proc_attrs -> ( + match proc_attrs.ProcAttributes.clang_method_kind with + | ClangMethodKind.OBJC_INSTANCE -> + true + | _ -> + false ) + | None -> + false + + let exec_instr (astate : Domain.t) {IntraproceduralAnalysis.proc_desc} _cfg_node _ (instr : Sil.instr) = let attributes = Procdesc.get_attributes proc_desc in @@ -387,8 +399,13 @@ module TransferFunctions = struct | Prune (UnOp (LNot, BinOp (Binop.Ne, Var id, e), _), _, _, _) when Exp.is_null_literal e (* if !(strongSef != nil) *) -> Domain.clear_unchecked_use id astate - | Call (_, Exp.Const (Const.Cfun _callee_pn), args, _, cf) -> - let fst = if cf.CallFlags.cf_virtual then List.hd args else None in + | Call (_, Exp.Const (Const.Cfun callee_pn), args, _, cf) -> + let fst = + if cf.CallFlags.cf_virtual then List.hd args + else + let attributes_opt = Attributes.load callee_pn in + if is_objc_instance attributes_opt then List.hd args else None + in let astate = Option.value_map ~f:(fun (arg, _) -> diff --git a/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m b/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m index b42bd8b4aa..74b6e9de62 100644 --- a/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m +++ b/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m @@ -434,4 +434,13 @@ - (void)strongSelfCheck11_good { }; } +- (void)strongSelfCheckCallingPropertyGetter_good { + __weak __typeof(self) weakSelf = self; + int (^my_block)(BOOL) = ^(BOOL isTapped) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + SelfInBlockTestUser* user = strongSelf.user; // no bug here + return 0; + }; +} + @end diff --git a/infer/tests/codetoanalyze/objc/self-in-block/issues.exp b/infer/tests/codetoanalyze/objc/self-in-block/issues.exp index e07f1a70d3..94225d378f 100644 --- a/infer/tests/codetoanalyze/objc/self-in-block/issues.exp +++ b/infer/tests/codetoanalyze/objc/self-in-block/issues.exp @@ -15,7 +15,7 @@ codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:121, 6, S codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:136, 2, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [Using &strongSelf] codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:158, 2, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [Using &strongSelf,Using &strongSelf] codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:170, 2, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [Using &strongSelf,Using &strongSelf] -codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:179, 2, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [Using &strongSelf,Using &strongSelf] +codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:179, 3, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [Using &strongSelf,Using &strongSelf] codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:208, 1, MULTIPLE_WEAKSELF, no_bucket, ERROR, [Using &weakSelf,Using &weakSelf] codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:229, 2, MULTIPLE_WEAKSELF, no_bucket, ERROR, [Using &weakSelf,Using &weakSelf] codetoanalyze/objc/self-in-block/StrongSelf.m, objc_block_StrongSelf.m:243, 1, CAPTURED_STRONG_SELF, no_bucket, ERROR, [Using captured &strongSelf,Using captured &strongSelf]