diff --git a/facebook-clang-plugins b/facebook-clang-plugins index c29650957..079dc15e1 160000 --- a/facebook-clang-plugins +++ b/facebook-clang-plugins @@ -1 +1 @@ -Subproject commit c29650957f6fcb8c82aa5da2c7b9971ede8677ac +Subproject commit 079dc15e1f37204632c61a4c09d3f82f78d0b1b7 diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 675dffd30..599339ac1 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -289,6 +289,14 @@ let is_objc_method_named an name = false +let is_objc_method_overriding an = + match an with + | Ctl_parser_types.Decl (Clang_ast_t.ObjCMethodDecl (_, _, mdi)) -> + mdi.omdi_is_overriding + | _ -> + false + + (* checks whether an object is of a certain class *) let is_object_of_class_named receiver cname = let open Clang_ast_t in diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index 9baaf5510..ebdbd67ea 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -237,6 +237,17 @@ val is_in_objc_method : CLintersContext.context -> ALVar.alexp -> bool * whose name matches the provided REGEXP *) +val is_objc_method_overriding : Ctl_parser_types.ast_node -> bool +(** + * Checks if the current node is an ObjCMethodDecl node and is overriding a + * method in the superclass. + * + * A method is said to override any method in the class's base classes, + * its protocols, or its categories' protocols, that has the same selector + * and is of the same kind (class or instance). A method in an implementation + * is not considered as overriding the same method in the interface or its categories. + *) + val captures_cxx_references : Ctl_parser_types.ast_node -> bool (** 'captures_cxx_references an' is true iff the node an captures some CXX references *) diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index ab041a120..a4eddf549 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -1066,6 +1066,8 @@ let rec eval_Atomic pred_name_ args an lcxt = CPredicates.is_objc_category_on_subclass_of an name | "is_objc_method_named", [name], an -> CPredicates.is_objc_method_named an name + | "is_objc_method_overriding", [], an -> + CPredicates.is_objc_method_overriding an | "is_property_pointer_type", [], an -> CPredicates.is_property_pointer_type an | "is_strong_property", [], an -> diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/linters_example.al b/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/linters_example.al index 046211d3c..021d47946 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/linters_example.al +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/linters_example.al @@ -585,3 +585,12 @@ DEFINE-CHECKER TEST_IF_IS_METHOD_NAMED = { SET message = "Node is a method named mySubclassMethod."; }; + +DEFINE-CHECKER TEST_IS_OVERRIDING_METHOD = { + + SET report_when = + is_objc_method_overriding; + + SET message = "Method %name% is overriding a method in a superclass."; + +}; 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 ba57f2803..974450949 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -1,5 +1,7 @@ codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase_testView, 17, TEST_VAR_TYPE_CHECK, WARNING, [] codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallComplain, 41, TEST_IF_VIEW_METHOD_IS_NOT_CALLED_WITH_SUPER, WARNING, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 27, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 44, TEST_IS_OVERRIDING_METHOD, WARNING, [] codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 45, TEST_VAR_TYPE_CHECK, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 14, TEST_IF_IS_CLASS_NAMED, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 21, TEST_IF_IS_CATEGORY_INTERFACE_ON_CLASS_NAMED, WARNING, [] @@ -24,12 +26,27 @@ codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseC codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassCategoryMethod, 53, TEST_IF_METHOD_IS_IN_CATEGORY_ON_CLASS_NAMED, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassInterfaceExtensionMethod, 23, TEST_IF_METHOD_IS_IN_CATEGORY_ON_CLASS_NAMED, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProperty, 37, TEST_RETURN_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProtocolOptionalMethod, 35, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProtocolRequiredMethod, 33, TEST_IS_OVERRIDING_METHOD, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_setMyBaseClassProperty, 40, TEST_PARAM_TYPE_CHECK2, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassCategoryMethod, 113, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassInterfaceExtensionMethod, 93, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassMethod, 89, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProperty, 105, TEST_IS_OVERRIDING_METHOD, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProperty, 105, TEST_RETURN_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProtocolOptionalMethod, 101, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProtocolRequiredMethod, 97, TEST_IS_OVERRIDING_METHOD, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassCategoryMethod, 136, TEST_IF_METHOD_IS_IN_CATEGORY_ON_SUBCLASS_OF, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassCategoryMethod, 142, TEST_IF_METHOD_IS_IN_CATEGORY_ON_SUBCLASS_OF, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassMethod, 83, TEST_IF_IS_METHOD_NAMED, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassMethod, 117, TEST_IF_IS_METHOD_NAMED, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocol2OptionalMethod, 125, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocol2RequiredMethod, 123, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocolOptionalMethod, 121, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocolRequiredMethod, 119, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassSubprotocol2OptionalMethod, 129, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassSubprotocol2RequiredMethod, 127, TEST_IS_OVERRIDING_METHOD, WARNING, [] +codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_setMyBaseClassProperty, 109, TEST_IS_OVERRIDING_METHOD, WARNING, [] codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_setMyBaseClassProperty, 109, TEST_PARAM_TYPE_CHECK2, WARNING, [] codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, InContextOfMethodsTest_method, 16, TEST_IN_METHOD_CONTEXT, WARNING, [] codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, InContextOfMethodsTest_method, 16, TEST_VAR_TYPE_CHECK, WARNING, []