From 766fc2c07229246e4f793ba59d15bd747bcf0ad6 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Tue, 26 Nov 2019 07:03:39 -0800 Subject: [PATCH] [AL] Adding a new transition to siblings Reviewed By: skcho Differential Revision: D18689255 fbshipit-source-id: f2b095382 --- facebook-clang-plugins | 2 +- infer/src/al/cTL.ml | 29 ++++++++++++++++++- infer/src/al/cTL.mli | 1 + infer/src/al/ctl_lexer.mll | 3 +- infer/src/al/ctl_parser.mly | 4 ++- .../al_definitions/linters_example.al | 15 ++++++++++ .../al_definitions/sibling_example.m | 13 +++++++++ .../objc/linters-for-test-only/issues.exp | 2 ++ 8 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m diff --git a/facebook-clang-plugins b/facebook-clang-plugins index b97ae1305..f691096a2 160000 --- a/facebook-clang-plugins +++ b/facebook-clang-plugins @@ -1 +1 @@ -Subproject commit b97ae1305b35e22ce80eeea28c5545c36a49db26 +Subproject commit f691096a2d34b81da7d6b05bfd4fffa280472f09 diff --git a/infer/src/al/cTL.ml b/infer/src/al/cTL.ml index 8a305e20f..34f5316f5 100644 --- a/infer/src/al/cTL.ml +++ b/infer/src/al/cTL.ml @@ -28,6 +28,7 @@ type transitions = | Cond | PointerToDecl (** stmt to decl *) | Protocol (** decl to decl *) + | Sibling (** decl to decl *) | SourceExpr [@@deriving compare] @@ -43,7 +44,7 @@ let is_transition_to_successor trans = | Cond | SourceExpr -> true - | Super | PointerToDecl | Protocol | AccessorForProperty _ -> + | Super | PointerToDecl | Protocol | AccessorForProperty _ | Sibling -> false @@ -158,6 +159,8 @@ module Debug = struct Format.pp_print_string fmt "Protocol" | PointerToDecl -> Format.pp_print_string fmt "PointerToDecl" + | Sibling -> + Format.pp_print_string fmt "Sibling" | SourceExpr -> Format.pp_print_string fmt "SourceExpr" in @@ -935,6 +938,28 @@ let transition_via_field_name node name = [] +let transition_via_sibling node = + let open Clang_ast_t in + match node with + | Decl orig_decl -> ( + let decl_info = Clang_ast_proj.get_decl_tuple orig_decl in + match CAst_utils.get_decl_opt decl_info.Clang_ast_t.di_parent_pointer with + | Some (TranslationUnitDecl (_, decls, _, _)) + | Some (ObjCImplementationDecl (_, _, decls, _, _)) + | Some (ObjCInterfaceDecl (_, _, decls, _, _)) + | Some (ObjCProtocolDecl (_, _, decls, _, _)) + | Some (ObjCCategoryDecl (_, _, decls, _, _)) + | Some (ObjCCategoryImplDecl (_, _, decls, _, _)) + | Some (RecordDecl (_, _, _, decls, _, _, _)) -> + List.filter_map + ~f:(fun decl -> if not (phys_equal decl orig_decl) then Some (Decl decl) else None) + decls + | _ -> + [] ) + | Stmt _ -> + [] + + (* given a node an returns a list of nodes an' such that an transition to an' via label trans *) let next_state_via_transition an trans = match (an, trans) with @@ -946,6 +971,8 @@ let next_state_via_transition an trans = transition_via_fields an | _, Parameters -> transition_via_parameters an + | _, Sibling -> + transition_via_sibling an | Decl d, InitExpr | Decl d, Body -> transition_decl_to_stmt d trans | Decl d, Protocol -> diff --git a/infer/src/al/cTL.mli b/infer/src/al/cTL.mli index 12c2a5d24..df0161622 100644 --- a/infer/src/al/cTL.mli +++ b/infer/src/al/cTL.mli @@ -28,6 +28,7 @@ type transitions = | Cond | PointerToDecl (** stmt to decl *) | Protocol (** decl to decl *) + | Sibling (** decl to decl *) | SourceExpr [@@deriving compare] diff --git a/infer/src/al/ctl_lexer.mll b/infer/src/al/ctl_lexer.mll index 7728d4b49..b53ee6e2a 100644 --- a/infer/src/al/ctl_lexer.mll +++ b/infer/src/al/ctl_lexer.mll @@ -83,7 +83,8 @@ rule token = parse | "InitExpr" {INIT_EXPR} | "Cond" {COND} | "PointerToDecl" {POINTER_TO_DECL} - | "SourceExpr" {SOURCE_EXPR} + | "Sibling" {SIBLING} + | "SourceExpr" {SOURCE_EXPR} | id { IDENTIFIER (Lexing.lexeme lexbuf) } | '"' { read_string (Buffer.create 80) lexbuf } | _ { raise (SyntaxError ("Unexpected char: '" ^ (Lexing.lexeme lexbuf) ^"'")) } diff --git a/infer/src/al/ctl_parser.mly b/infer/src/al/ctl_parser.mly index da8e02b6b..1a5acd39b 100644 --- a/infer/src/al/ctl_parser.mly +++ b/infer/src/al/ctl_parser.mly @@ -86,6 +86,7 @@ %token PARAMETER_NAME %token PARAMETER_POS %token POINTER_TO_DECL +%token SIBLING %token SOURCE_EXPR %token PROTOCOL %token EOF @@ -250,8 +251,9 @@ transition_label: | PARAMETER_NAME alexp { Some (CTL.ParameterName $2) } | PARAMETER_POS alexp { Some (CTL.ParameterPos $2) } | POINTER_TO_DECL { Some CTL.PointerToDecl } - | SOURCE_EXPR { Some CTL.SourceExpr} | PROTOCOL { Some CTL.Protocol } + | SIBLING { Some CTL.Sibling} + | SOURCE_EXPR { Some CTL.SourceExpr} ; formula_EF: 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 9b0c42779..14bc94989 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 @@ -896,4 +896,19 @@ SET report_when = WHEN is_create_method_parameter HOLDS-IN-NODE CallExpr; +}; + +DEFINE-CHECKER CLASS_AND_VAR = { + LET global_var_exists = + is_node("VarDecl"); + + LET var_decl = + (HOLDS-NEXT WITH-TRANSITION Sibling + (global_var_exists())); + + SET report_when = + WHEN var_decl() AND declaration_has_name("SiblingExample") + HOLDS-IN-NODE ObjCInterfaceDecl; + + SET message = "Found a global var next to a class"; }; \ No newline at end of file diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m b/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m new file mode 100644 index 000000000..8d9f755c5 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m @@ -0,0 +1,13 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#import + +int x; + +@interface SiblingExample : NSObject + +@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 6795e9661..a0269aa7f 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -227,6 +227,8 @@ codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass:: codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 11, TEST_RETURN_METHOD, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_IS_METHOD_EXPOSED, no_bucket, WARNING, [] codetoanalyze/objc/linters-for-test-only/PrivateInstanceMethod.m, UselessClass::b, 18, TEST_RETURN_METHOD, no_bucket, WARNING, [] +codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m, Linters_dummy_method, 9, TEST_VAR_TYPE_CHECK, no_bucket, WARNING, [] +codetoanalyze/objc/linters-for-test-only/al_definitions/sibling_example.m, Linters_dummy_method, 11, CLASS_AND_VAR, 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, []