From 634a42b61931f8d4c4a9f4acccd52f9ac3f3e769 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Tue, 3 Mar 2020 10:11:58 -0800 Subject: [PATCH] [SelfInBlock] Take ns_noescape into account when reporting captured strong self. Summary: When reporting CapturedStrongSelf we shouldn't report it when the block is "no escaping", as this won't lead to a retain cycle, so capturing strongSelf is ok. Reviewed By: jvillard Differential Revision: D20224359 fbshipit-source-id: c60dae333 --- infer/src/checkers/SelfInBlock.ml | 9 +++++--- .../objc/self-in-block/StrongSelf.m | 23 ++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/infer/src/checkers/SelfInBlock.ml b/infer/src/checkers/SelfInBlock.ml index 1d61f1fe4..383611b95 100644 --- a/infer/src/checkers/SelfInBlock.ml +++ b/infer/src/checkers/SelfInBlock.ml @@ -471,9 +471,12 @@ let report_weakself_multiple_issue summary domain (weakSelf1 : DomainData.t) Reporting.log_error summary ~ltr ~loc:weakSelf1.loc IssueType.multiple_weakself message -let report_captured_strongself_issue domain summary (capturedStrongSelf : DomainData.t) +let report_captured_strongself_issue domain summary attributes (capturedStrongSelf : DomainData.t) report_captured_strongself = - if not (Pvar.Set.mem capturedStrongSelf.pvar report_captured_strongself) then ( + if + Option.is_none attributes.ProcAttributes.passed_as_noescape_block_to + && not (Pvar.Set.mem capturedStrongSelf.pvar report_captured_strongself) + then ( let report_captured_strongself = Pvar.Set.add capturedStrongSelf.pvar report_captured_strongself in @@ -496,7 +499,7 @@ let report_issues summary domain attributes = match domain_data.kind with | DomainData.CAPTURED_STRONG_SELF -> let reported_captured_strong_self = - report_captured_strongself_issue domain summary domain_data + report_captured_strongself_issue domain summary attributes domain_data result.reported_captured_strong_self in {result with reported_captured_strong_self} diff --git a/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m b/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m index 61b65f7ec..91e4471a0 100644 --- a/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m +++ b/infer/tests/codetoanalyze/objc/self-in-block/StrongSelf.m @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -#include +#include @class SelfInBlockTest; @@ -31,6 +31,8 @@ - (void)bar; +- (A*)process:(A*)obj; + @end void m(SelfInBlockTest* obj) {} @@ -47,6 +49,10 @@ void m2(_Nullable SelfInBlockTest* obj) {} - (void)bar { } +- (A*)process:(A*)obj { + return obj; +} + - (void)mixSelfWeakSelf_bad { __weak __typeof(self) weakSelf = self; int (^my_block)() = ^() { @@ -218,6 +224,21 @@ void m2(_Nullable SelfInBlockTest* obj) {} }; } +- (void)capturedStrongSelf_good:(NSArray*)allResults { + __weak __typeof(self) weakSelf = self; + int (^my_block)() = ^() { + __strong typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [allResults + enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop) { + A* result = + [strongSelf process:obj]; // no bug because of NS_NOESCAPE flag + }]; + } + return 0; + }; +} + - (void)mixSelfWeakSelf_good:(NSArray*)resources { __weak __typeof(self) weakSelf = self; int (^my_block)() = ^() {