[AL] Improve the predicate for checking visibility attribute and example rule for checking macro for category implementation

Reviewed By: skcho

Differential Revision: D18744625

fbshipit-source-id: 10b0c77b5
master
Dulma Churchill 5 years ago committed by Facebook Github Bot
parent 48da570aa0
commit c9c4adebc2

@ -1391,21 +1391,23 @@ let using_namespace an namespace =
false
let rec get_decl_attributes_for_callexpr an =
let rec get_decl_attributes an =
let open Clang_ast_t in
let open Ctl_parser_types in
match an with
| Stmt (CallExpr (_, func :: _, _)) ->
get_decl_attributes_for_callexpr (Stmt func)
get_decl_attributes (Stmt func)
| Stmt (ImplicitCastExpr (_, [stmt], _, _)) ->
get_decl_attributes_for_callexpr (Stmt stmt)
get_decl_attributes (Stmt stmt)
| Stmt (DeclRefExpr (_, _, _, drti)) -> (
match CAst_utils.get_decl_opt_with_decl_ref drti.drti_decl_ref with
| Some decl ->
let decl_info = Clang_ast_proj.get_decl_tuple decl in
decl_info.di_attributes
get_decl_attributes (Decl decl)
| None ->
[] )
| Decl decl ->
let decl_info = Clang_ast_proj.get_decl_tuple decl in
decl_info.di_attributes
| _ ->
[]
@ -1452,7 +1454,7 @@ let has_visibility_attribute an visibility =
| _ ->
false )
in
let attributes = get_decl_attributes_for_callexpr an in
let attributes = get_decl_attributes an in
match visibility with ALVar.Const vis -> has_visibility_attr attributes vis | _ -> false
@ -1462,7 +1464,7 @@ let has_no_escape_attribute an =
let has_used_attribute an =
let attributes = get_decl_attributes_for_callexpr an in
let attributes = get_decl_attributes an in
List.exists ~f:(fun attr -> match attr with `UsedAttr _ -> true | _ -> false) attributes

@ -932,5 +932,26 @@ DEFINE-CHECKER CAT_DECL_MACRO = {
)
HOLDS-IN-NODE ObjCCategoryDecl;
SET message = "A category is defined without the corrsponding macro";
SET message = "A category is defined without the corresponding macro";
};
DEFINE-CHECKER CAT_IMPL_MACRO = {
LET is_linkable_var =
has_visibility_attribute("Default") AND
declaration_has_name(REGEXP("Linkable_.*")) AND
has_type("char");
LET var_decls =
HOLDS-NEXT WITH-TRANSITION Sibling
(is_node("VarDecl") AND is_linkable_var());
SET report_when =
WHEN
NOT (
is_node("ObjCCategoryImplDecl")
AND-WITH-WITNESSES var_decls() : decl_name_is_contained_in_name_of_decl()
) HOLDS-IN-NODE ObjCCategoryImplDecl;
SET message = "A category is implemented without the corresponding macro";
};

@ -17,8 +17,18 @@ int x;
extern const void* const OS_WEAK OS_CONCAT(Link_, NAME); \
OS_USED const void* const OS_WEAK OS_CONCAT(Link_, NAME) = &Linkable_##NAME;
#define LINKABLE(NAME) \
__attribute__((visibility("default"))) char Linkable_##NAME = 'L';
LINK_REQUIRE(SiblingExample_Cat2);
@interface SiblingExample (Cat2)
- (void)foo:(int)themeProvider;
@end
LINKABLE(SiblingExample)
@implementation SiblingExample (Cat2)
- (void)foo:(int)themeProvider {
}
@end

@ -26,6 +26,7 @@ codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_metho
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_INTERFACE_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 76, TEST_IF_IS_CATEGORY_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, CAT_IMPL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_IMPLEMENTATION_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_IMPLEMENTATION_ON_CLASS_NAMED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 82, TEST_IF_IS_CATEGORY_NAMED, no_bucket, WARNING, []
@ -33,6 +34,7 @@ codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_metho
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, TEST_IF_IS_CATEGORY_INTERFACE_ON_SUBCLASS_OF, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 183, TEST_IF_IS_CATEGORY_ON_SUBCLASS_OF, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 189, CAT_IMPL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 189, TEST_IF_IS_CATEGORY_IMPLEMENTATION_ON_SUBCLASS_OF, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 189, TEST_IF_IS_CATEGORY_ON_SUBCLASS_OF, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass::myBaseClassCategoryMethod, 78, TEST_IF_METHOD_IS_IN_CATEGORY_INTERFACE_NAMED, no_bucket, WARNING, []
@ -232,8 +234,11 @@ codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::
codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_RETURN_METHOD, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 9, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 11, CLASS_AND_VAR, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 20, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, SiblingExample::foo, 22, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 23, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, Linters_dummy_method, 29, CAT_IMPL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, SiblingExample::foo, 25, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, SiblingExample::foo, 31, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/cat_macro_example.m, SiblingExample::foo, 31, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 7, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 7, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/const.m, Linters_dummy_method, 8, CONST_NAMING, no_bucket, WARNING, []
@ -281,11 +286,16 @@ codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent::newWithActio
codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent::newWithAction, 10, TEST_PARAMETER_SEL_TYPE, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 9, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 11, CLASS_AND_VAR, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 20, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 25, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 26, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 21, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 27, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 23, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 28, CONST_NAMING, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 29, CAT_DECL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, Linters_dummy_method, 42, CAT_IMPL_MACRO, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 24, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 30, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 37, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 37, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 44, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/sibling_example.m, SiblingExample::foo, 44, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 11, TEST_PARAM_TYPE_CHECK2, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 11, TEST_RETURN_METHOD, no_bucket, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A::foo, 17, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, []

@ -17,6 +17,9 @@ int x;
extern const void* const OS_WEAK OS_CONCAT(Link_, NAME); \
OS_USED const void* const OS_WEAK OS_CONCAT(Link_, NAME) = &Linkable_##NAME;
#define LINKABLE(NAME) \
__attribute__((visibility("default"))) char Linkable_##NAME = 'L';
@interface SiblingExample (Cat1)
- (void)foo:(int)themeProvider;
@ -27,3 +30,17 @@ LINK_REQUIRE(SiblingExampl);
- (void)foo:(int)themeProvider;
@end
LINKABLE(SiblingExample_Cat2)
@implementation SiblingExample (Cat2)
- (void)foo:(int)themeProvider {
}
@end
@implementation SiblingExample (Cat1)
- (void)foo:(int)themeProvider {
}
@end

Loading…
Cancel
Save