From 1f14ab94e93e83e4344a437f57822de1cd6a523c Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Tue, 19 Nov 2024 02:16:22 -0800 Subject: [PATCH] [self-in-block] Do not report on instance method calls Summary: We want to stop reporting when strongSelf is the receiver of instance method calls because that's not a crash. Previously we were checking the virtual call flags but that was not enough for checking getters and setters of properties, so we are now also checking the instance property of the callee method. Reviewed By: ngorogiannis Differential Revision: D66101550 fbshipit-source-id: f11e248845ef698a95695a73140dc36608fbc919 --- infer/src/checkers/SelfInBlock.ml | 21 +++++++++++++++++-- .../objc/self-in-block/StrongSelf.m | 9 ++++++++ .../objc/self-in-block/issues.exp | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) 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]