From 8cfc7f2cada7c2e3c37f629aa1c34cd0e8f8de28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Marguerie?= Date: Wed, 28 Feb 2018 10:24:47 -0800 Subject: [PATCH] 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 --- infer/src/clang/cPredicates.ml | 35 +++++++++++++++++++ infer/src/clang/cPredicates.mli | 2 ++ infer/src/clang/cTL.ml | 2 ++ infer/src/clang/ctl_parser_types.ml | 2 ++ .../objc/linters-def-folder/Makefile | 2 +- .../linters-def-folder/checks/dummy_check.al | 8 +++++ .../objc/linters-def-folder/file.m | 7 +++- .../objc/linters-def-folder/issues.exp | 2 ++ 8 files changed, 58 insertions(+), 2 deletions(-) diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index f6bc175c1..cb0fd3303 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -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 diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index 0cf962de6..b696db1a8 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -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 diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index 8c860a403..287503023 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -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 -> diff --git a/infer/src/clang/ctl_parser_types.ml b/infer/src/clang/ctl_parser_types.ml index d2c56d3df..823eb25da 100644 --- a/infer/src/clang/ctl_parser_types.ml +++ b/infer/src/clang/ctl_parser_types.ml @@ -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 diff --git a/infer/tests/codetoanalyze/objc/linters-def-folder/Makefile b/infer/tests/codetoanalyze/objc/linters-def-folder/Makefile index 0714660fe..79e0fc92d 100644 --- a/infer/tests/codetoanalyze/objc/linters-def-folder/Makefile +++ b/infer/tests/codetoanalyze/objc/linters-def-folder/Makefile @@ -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 diff --git a/infer/tests/codetoanalyze/objc/linters-def-folder/checks/dummy_check.al b/infer/tests/codetoanalyze/objc/linters-def-folder/checks/dummy_check.al index 943f320f4..11cbabd8e 100644 --- a/infer/tests/codetoanalyze/objc/linters-def-folder/checks/dummy_check.al +++ b/infer/tests/codetoanalyze/objc/linters-def-folder/checks/dummy_check.al @@ -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."; +}; diff --git a/infer/tests/codetoanalyze/objc/linters-def-folder/file.m b/infer/tests/codetoanalyze/objc/linters-def-folder/file.m index 436fe3472..e06f336c5 100644 --- a/infer/tests/codetoanalyze/objc/linters-def-folder/file.m +++ b/infer/tests/codetoanalyze/objc/linters-def-folder/file.m @@ -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 diff --git a/infer/tests/codetoanalyze/objc/linters-def-folder/issues.exp b/infer/tests/codetoanalyze/objc/linters-def-folder/issues.exp index f668b2d80..559bc33d3 100644 --- a/infer/tests/codetoanalyze/objc/linters-def-folder/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-def-folder/issues.exp @@ -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, []