From 89700a7d9541c0a8ea113a589e61eada03f7abd7 Mon Sep 17 00:00:00 2001 From: Dino Distefano Date: Tue, 9 Oct 2018 00:23:15 -0700 Subject: [PATCH] Added new predicated for captured values Reviewed By: jvillard Differential Revision: D10162271 fbshipit-source-id: 47f9420b8 --- infer/src/clang/cPredicates.ml | 8 +++++ infer/src/clang/cPredicates.mli | 3 ++ infer/src/clang/cTL.ml | 2 ++ .../objcpp/linters-for-test-only/issues.exp | 1 + .../linters-for-test-only/linters_example.al | 11 ++++++ .../objcpp/linters-for-test-only/static.m | 35 +++++++++++++++++++ 6 files changed, 60 insertions(+) create mode 100644 infer/tests/codetoanalyze/objcpp/linters-for-test-only/static.m diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index abae8b867..d6bd711ef 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -138,6 +138,14 @@ let captured_variables_cxx_ref an = [] +let objc_block_is_capturing_values an = + match an with + | Ctl_parser_types.Decl (Clang_ast_t.BlockDecl (_, bdi)) -> + not (List.is_empty bdi.bdi_captured_variables) + | _ -> + false + + type t = ALVar.formula_id * (* (name, [param1,...,paramK]) *) ALVar.alexp list [@@deriving compare] let pp_predicate fmt (name_, arglist_) = diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index a1b6c0ca1..5cf246939 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -14,6 +14,9 @@ type t = ALVar.formula_id * ALVar.alexp list [@@deriving compare] val captured_variables_cxx_ref : Ctl_parser_types.ast_node -> Clang_ast_t.named_decl_info list (** list of cxx references captured by an ObjC Block *) +val objc_block_is_capturing_values : Ctl_parser_types.ast_node -> bool +(** true if the ObjC Block captures any variables *) + val call_method : Ctl_parser_types.ast_node -> ALVar.alexp -> bool (** 'call_method an m an' is true iff node an is a call to an ObjC method with name containing string m *) diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index 8eca1a94d..e877ef7e8 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -972,6 +972,8 @@ let rec eval_Atomic pred_name_ args an lcxt = CPredicates.call_method an m | "captures_cxx_references", [], _ -> CPredicates.captures_cxx_references an + | "objc_block_is_capturing_values", [], _ -> + CPredicates.objc_block_is_capturing_values an | "context_in_synchronized_block", [], _ -> CPredicates.context_in_synchronized_block lcxt | "declaration_has_name", [decl_name], an -> diff --git a/infer/tests/codetoanalyze/objcpp/linters-for-test-only/issues.exp b/infer/tests/codetoanalyze/objcpp/linters-for-test-only/issues.exp index a2ae8bf2e..9b7c52eab 100644 --- a/infer/tests/codetoanalyze/objcpp/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objcpp/linters-for-test-only/issues.exp @@ -27,3 +27,4 @@ codetoanalyze/objcpp/linters-for-test-only/TestStructFieldChecks.mm, buttonCompo codetoanalyze/objcpp/linters-for-test-only/TestStructFieldChecks.mm, buttonComponent, 33, TITLE_NOT_INITIALIZED, no_bucket, WARNING, [] codetoanalyze/objcpp/linters-for-test-only/TestStructFieldChecks.mm, buttonComponent, 37, TITLE_NOT_INITIALIZED, no_bucket, WARNING, [] codetoanalyze/objcpp/linters-for-test-only/hash_test.mm, std::hash_NSObject_*__operator(), 12, DISCOURAGED_HASH_METHOD_INVOCATION, no_bucket, WARNING, [] +codetoanalyze/objcpp/linters-for-test-only/static.m, objc_block_1, 18, OBJC_BLOCK_CAPTURING_VALUES, no_bucket, WARNING, [] diff --git a/infer/tests/codetoanalyze/objcpp/linters-for-test-only/linters_example.al b/infer/tests/codetoanalyze/objcpp/linters-for-test-only/linters_example.al index 433a76b9f..554fdd83e 100644 --- a/infer/tests/codetoanalyze/objcpp/linters-for-test-only/linters_example.al +++ b/infer/tests/codetoanalyze/objcpp/linters-for-test-only/linters_example.al @@ -198,3 +198,14 @@ DEFINE-CHECKER FIELD_STRUCT_STRING = { SET severity = "WARNING"; SET mode = "ON"; }; + +DEFINE-CHECKER OBJC_BLOCK_CAPTURING_VALUES = { + + SET report_when = + WHEN + objc_block_is_capturing_values() + HOLDS-IN-NODE BlockDecl; + + SET message = "ObjC Block capturing values"; + SET mode = "ON"; +}; diff --git a/infer/tests/codetoanalyze/objcpp/linters-for-test-only/static.m b/infer/tests/codetoanalyze/objcpp/linters-for-test-only/static.m new file mode 100644 index 000000000..dee03aad2 --- /dev/null +++ b/infer/tests/codetoanalyze/objcpp/linters-for-test-only/static.m @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +@interface A : NSObject + +@end + +@implementation A + ++ (instancetype)test { + static id sharedInstance; + ^{ + sharedInstance = [[self alloc] init]; + }(); + + return sharedInstance; +} + ++ (int)testOK { + static int i; + + ^{ + int j = 0; + }(); + + return i; +} + +@end