[SelfInBlock] Report strongSelf Not Checked when strongSelf passed to a function as argument

Summary: Adding reporting to strongSelf Not Checked  when strongSelf is passed to a method in a not explicitly nullable position.

Reviewed By: ezgicicek

Differential Revision: D19330872

fbshipit-source-id: 95871a70a
master
Dulma Churchill 5 years ago committed by Facebook Github Bot
parent 05bd4185e0
commit 66c6a73cc6

@ -226,6 +226,56 @@ module TransferFunctions = struct
List.iter ~f:report_unchecked_strongself_issues_on_exp exps
let is_objc_instance proc_desc_opt =
match proc_desc_opt with
| Some proc_desc -> (
let proc_attrs = Procdesc.get_attributes proc_desc in
match proc_attrs.ProcAttributes.clang_method_kind with
| ClangMethodKind.OBJC_INSTANCE ->
true
| _ ->
false )
| None ->
false
let get_annotations proc_desc_opt =
match proc_desc_opt with
| Some proc_desc ->
let proc_attrs = Procdesc.get_attributes proc_desc in
Some proc_attrs.ProcAttributes.method_annotation.params
| None ->
None
let report_unchecked_strongself_issues_on_args (domain : Domain.t) summary pname args =
let report_issue var =
report_unchecked_strongself_issues summary domain
(F.sprintf "passed to %s" (Procname.to_simplified_string pname))
var
in
let rec report_on_non_nullable_arg ?(annots = []) args =
match (annots, args) with
| annot :: annot_rest, (Exp.Var var, _) :: rest when not (Annotations.ia_is_nullable annot) ->
report_issue var ;
report_on_non_nullable_arg ~annots:annot_rest rest
| [], (Exp.Var var, _) :: rest ->
report_issue var ; report_on_non_nullable_arg rest
| _ ->
()
in
let proc_desc_opt = Ondemand.get_proc_desc pname in
let args =
if is_objc_instance proc_desc_opt then match args with _ :: rest -> rest | [] -> []
else args
in
match get_annotations proc_desc_opt with
| Some annotations ->
report_on_non_nullable_arg ~annots:annotations args
| None ->
report_on_non_nullable_arg args
let exec_instr (astate : Domain.t) {ProcData.summary} _cfg_node (instr : Sil.instr) =
let attributes = Summary.get_attributes summary in
report_unchecked_strongself_issues_on_exps astate summary instr ;
@ -262,6 +312,9 @@ module TransferFunctions = struct
(* If (!(strongSelf == nil)) or equivalent else branch *)
| Prune (UnOp (LNot, BinOp (Binop.Eq, Var id, e), _), _, _, Sil.Ik_if) ->
if Exp.is_null_literal e then exec_null_check_id astate id else astate
| Call (_, Exp.Const (Const.Cfun callee_pn), args, _, _) ->
report_unchecked_strongself_issues_on_args astate summary callee_pn args ;
astate
| _ ->
astate
end

@ -7,14 +7,31 @@
#include <Foundation/NSObject.h>
@class SelfInBlockTest;
@interface SelfInBlockTestUser
- (void)use_self_in_block_test:(SelfInBlockTest*)test;
- (void)use_self_in_block_test_nullable:(int)x
and:(_Nullable SelfInBlockTest*)test;
@end
@interface SelfInBlockTest : NSObject
@property(nonatomic, weak) SelfInBlockTestUser* user;
- (void)foo;
- (void)bar;
@end
void m(SelfInBlockTest* obj) {}
void m2(_Nullable SelfInBlockTest* obj) {}
@implementation SelfInBlockTest {
int x;
}
@ -74,7 +91,15 @@
[strongSelf foo];
int x = strongSelf->x;
} else {
strongSelf->x;
strongSelf->x; // bug here
[strongSelf foo]; // no bug here
m(strongSelf); // bug here
m2(strongSelf); // no bug here because of _Nullable annotation
[strongSelf.user use_self_in_block_test:strongSelf]; // bug here
[strongSelf.user
use_self_in_block_test_nullable:1
and:strongSelf]; // no bug here because of
// _Nullable annotation
}
[strongSelf foo];
if (strongSelf != nil) {

@ -1,4 +1,6 @@
codetoanalyze/objc/self-in-block/StrongSelf.m, objc_blockSelfInBlockTest::mixSelfWeakSelf_bad_1, 5, MIXED_SELF_WEAKSELF, no_bucket, ERROR, [Using &weakSelf,Using &self,Using &self]
codetoanalyze/objc/self-in-block/StrongSelf.m, objc_blockSelfInBlockTest::strongSelfCheck3_bad_7, 2, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [&strongSelf assigned here,Using &strongSelf not checked for null]
codetoanalyze/objc/self-in-block/StrongSelf.m, objc_blockSelfInBlockTest::strongSelfCheckOnce_bad_5, 6, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [&strongSelf assigned here,Using &strongSelf not checked for null,Using &strongSelf not checked for null]
codetoanalyze/objc/self-in-block/StrongSelf.m, objc_blockSelfInBlockTest::strongSelfCheckOnce_bad_5, 8, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [&strongSelf assigned here,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null]
codetoanalyze/objc/self-in-block/StrongSelf.m, objc_blockSelfInBlockTest::strongSelfCheckOnce_bad_5, 10, STRONG_SELF_NOT_CHECKED, no_bucket, ERROR, [&strongSelf assigned here,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null,Using &strongSelf not checked for null]
codetoanalyze/objc/self-in-block/StrongSelf.m, objc_blockSelfInBlockTest::wekSelfMultiple_bad_9, 1, MULTIPLE_WEAKSELF, no_bucket, ERROR, [Using &weakSelf,Using &weakSelf]

Loading…
Cancel
Save