From d8be5e0874068df19873398ca95cf232fd514473 Mon Sep 17 00:00:00 2001 From: Vivek Dhiman Date: Tue, 14 Nov 2017 03:39:36 -0800 Subject: [PATCH] Added 'is_method_called_by_superclass'. A new predicate that checks if the caller name is super class in a 'method call'. Reviewed By: dulmarod Differential Revision: D6311990 fbshipit-source-id: 5c9919c --- infer/src/clang/cPredicates.ml | 10 ++++ infer/src/clang/cPredicates.mli | 2 + infer/src/clang/cTL.ml | 3 +- .../CallingAMethodWithSelf.m | 47 +++++++++++++++++++ .../objc/linters-for-test-only/issues.exp | 12 +++++ .../linters-for-test-only/linters_example.al | 12 +++++ 6 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 infer/tests/codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index aa37edba3..7da2ea36a 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -871,3 +871,13 @@ let has_value an al_exp = | _ -> false + +(* check if method is called on superclass *) +let is_method_called_by_superclass an = + let open Clang_ast_t in + let open Ctl_parser_types in + match an with + | Stmt ObjCMessageExpr (_, _, _, obj_c_message_expr_info) -> ( + match obj_c_message_expr_info.omei_receiver_kind with `SuperInstance -> true | _ -> false ) + | _ -> + false diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index 345b2b69e..067e28bc6 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -140,3 +140,5 @@ val has_type_const_ptr_to_objc_class : Ctl_parser_types.ast_node -> bool val is_decl : Ctl_parser_types.ast_node -> bool val get_ast_node_type_ptr : Ctl_parser_types.ast_node -> Clang_ast_t.type_ptr option + +val is_method_called_by_superclass : Ctl_parser_types.ast_node -> bool diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index 43fe164f4..147d9f6a2 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -1064,6 +1064,8 @@ let rec eval_Atomic _pred_name args an lcxt = CPredicates.has_used_attribute an | "within_available_class_block", [], an -> CPredicates.within_available_class_block lcxt an + | "is_method_called_by_superclass", [], an -> + CPredicates.is_method_called_by_superclass an | _ -> L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name @@ -1251,4 +1253,3 @@ and eval_formula f an lcxt : Ctl_parser_types.ast_node option = eval_ET tl sw phi an lcxt in debug_eval_end res ; res - diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m b/infer/tests/codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m new file mode 100644 index 000000000..354587f42 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +@interface CallingAMethodWithSelfBase +- (void)testView; +@end + +@implementation CallingAMethodWithSelfBase + +- (void)testView { + int k = 0; +} +@end + +@interface CallingAMethodWithSelf : CallingAMethodWithSelfBase + +- (void)methodThatShallNotComplain; + +- (void)methodThatShallComplain; + +- (void)testView; +@end + +@implementation CallingAMethodWithSelf + +- (void)methodThatShallBeOkayVoid { + testView(); +} + +- (void)methodThatShallBeOkaySuper { + [super testView]; +} + +- (void)methodThatShallComplain { + [self testView]; +} + +- (void)testView { + int p = 0; +} +@end diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp index b4da75588..1d0c45cf3 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -1,3 +1,15 @@ +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase_testView, 11, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase_testView, 16, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase_testView, 17, TEST_VAR_TYPE_CHECK, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallBeOkaySuper, 36, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallBeOkayVoid, 32, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallComplain, 25, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallComplain, 40, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallComplain, 41, TEST_IF_VIEW_METHOD_IS_NOT_CALLED_WITH_SUPER, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallNotComplain, 23, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 27, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 44, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 45, TEST_VAR_TYPE_CHECK, [] codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, InContextOfMethodsTest_method, 15, TEST_BUILTIN_TYPE, [] codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, InContextOfMethodsTest_method, 16, TEST_IN_METHOD_CONTEXT, [] codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, InContextOfMethodsTest_method, 16, TEST_VAR_TYPE_CHECK, [] diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al b/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al index 0d840cd34..f6be49595 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al @@ -430,3 +430,15 @@ DEFINE-CHECKER TEST_PARAMETER_SEL_TYPE = { HOLDS-IN-NODE ObjCMessageExpr; SET message = "Found a message call in a class that is not subclass of A."; }; + + DEFINE-CHECKER TEST_IF_VIEW_METHOD_IS_NOT_CALLED_WITH_SUPER = { + + SET report_when = + WHEN + call_method("testView") AND + NOT is_method_called_by_superclass() + HOLDS-IN-NODE ObjCMessageExpr; + + SET message = "Method %name% is not called with super."; + +};