Add function to retrieve the lifetime of an ivar pointer and check if it is strong

Reviewed By: dulmarod

Differential Revision: D7099861

fbshipit-source-id: b0edbeb
master
Jérémie Marguerie 7 years ago committed by Facebook Github Bot
parent 7cc0946a5a
commit 8cfc7f2cad

@ -723,6 +723,41 @@ let has_type_const_ptr_to_objc_class node =
false
(* Return the lifetime of the pointer of an expression if it is of type AttributedType *)
(* This is useful to check the lifetime of ivars *)
(* @returns objc_lifetime_attr *)
let get_ivar_lifetime an =
match get_ast_node_type_ptr an with
| Some pt -> (
match CAst_utils.get_type pt with
| Some c_type
-> (
L.(debug Linters Medium) "@\nChecking type: `%s`\n" (Clang_ast_j.string_of_c_type c_type) ;
let open Clang_ast_t in
match c_type with
| AttributedType (_, attr_info) ->
Some attr_info.Clang_ast_t.ati_lifetime
| ObjCObjectPointerType _ ->
Some `OCL_Strong
| _ ->
L.(debug Linters Medium) "Pointer is not of type AttributedType...@\n" ;
None )
| _ ->
L.(debug Linters Medium) "Couldn't find type....\n" ;
None )
| _ ->
L.(debug Linters Medium) "Couldn't find pointer...@\n" ;
None
let is_strong_ivar an =
match get_ivar_lifetime an with
| Some lifetime -> (
match lifetime with `OCL_Strong | `OCL_Autoreleasing | `OCL_None -> true | _ -> false )
| _ ->
false
let is_decl node =
match node with Ctl_parser_types.Decl _ -> true | Ctl_parser_types.Stmt _ -> false

@ -39,6 +39,8 @@ val call_function : Ctl_parser_types.ast_node -> ALVar.alexp -> bool
val is_strong_property : Ctl_parser_types.ast_node -> bool
val is_strong_ivar : Ctl_parser_types.ast_node -> bool
val is_weak_property : Ctl_parser_types.ast_node -> bool
val is_assign_property : Ctl_parser_types.ast_node -> bool

@ -1041,6 +1041,8 @@ let rec eval_Atomic pred_name_ args an lcxt =
CPredicates.is_property_pointer_type an
| "is_strong_property", [], an ->
CPredicates.is_strong_property an
| "is_strong_ivar", [], an ->
CPredicates.is_strong_ivar an
| "is_unop_with_kind", [kind], an ->
CPredicates.is_unop_with_kind an kind
| "is_weak_property", [], an ->

@ -514,6 +514,8 @@ and c_type_equal c_type abs_ctype =
typename_equal tdi.tti_decl_ptr ae
| TypedefType (ti, _), ObjCGenProt _ -> (
match ti.ti_desugared_type with Some dt -> check_type_ptr dt abs_ctype | None -> false )
| AttributedType (ti, _), Pointer _ -> (
match ti.ti_desugared_type with Some dt -> check_type_ptr dt abs_ctype | None -> false )
| _, _ ->
display_equality_warning () ; false

@ -8,7 +8,7 @@
TESTS_DIR = ../../..
ANALYZER = linters
CLANG_OPTIONS = -c
CLANG_OPTIONS = -c -fobjc-arc
INFER_OPTIONS = --linters-def-folder checks --project-root $(TESTS_DIR)
INFERPRINT_OPTIONS = --issues-tests

@ -9,3 +9,11 @@ DEFINE-CHECKER FORBIDDEN_NAME_EXAMPLE = {
SET report_when = WHEN is_class("ForbiddenClassName") HOLDS-IN-NODE ObjCInterfaceDecl;
SET message = "ForbiddenClassName is forbidden, please use another name";
};
DEFINE-CHECKER STRONG_UIAPPLICATION_WARNING = {
SET report_when =
WHEN has_type("A *") AND is_strong_ivar()
HOLDS-IN-NODE ObjCIvarDecl;
SET message = "Ivar %decl_name% strongly retain A.";
};

@ -32,5 +32,10 @@
@interface C : NSObject
@end
@implementation C
@implementation C {
__strong A* _app1;
__weak A* _app2;
A* _app3;
__unsafe_unretained A* _app4;
}
@end

@ -1,2 +1,4 @@
codetoanalyze/objc/linters-def-folder/file.m, Linters_dummy_method, 20, SUBCLASSING_TEST_EXAMPLE, []
codetoanalyze/objc/linters-def-folder/file.m, Linters_dummy_method, 26, FORBIDDEN_NAME_EXAMPLE, []
codetoanalyze/objc/linters-def-folder/file.m, Linters_dummy_method, 36, STRONG_UIAPPLICATION_WARNING, []
codetoanalyze/objc/linters-def-folder/file.m, Linters_dummy_method, 38, STRONG_UIAPPLICATION_WARNING, []

Loading…
Cancel
Save