From cfd0a9b038e2b5d27e03ff7af87d5a1b87e71def Mon Sep 17 00:00:00 2001 From: Dino Distefano Date: Thu, 18 May 2017 07:21:00 -0700 Subject: [PATCH] Extending type parser to parse ObjC classes. Reviewed By: dulmarod Differential Revision: D5052238 fbshipit-source-id: b678c32 --- infer/src/clang/ALVar.ml | 21 ++++ infer/src/clang/ALVar.mli | 2 + infer/src/clang/cPredicates.ml | 58 ++++------ infer/src/clang/ctl_parser_types.ml | 109 +++++++++++------- infer/src/clang/ctl_parser_types.mli | 3 +- infer/src/clang/types_lexer.mll | 18 +++ infer/src/clang/types_parser.mly | 21 +++- .../objc/linters-for-test-only/issues.exp | 44 +++---- .../linters-for-test-only/linters_example.al | 2 + .../objc/linters-for-test-only/subclassing.m | 9 +- 10 files changed, 190 insertions(+), 97 deletions(-) diff --git a/infer/src/clang/ALVar.ml b/infer/src/clang/ALVar.ml index e9feff65c..f42339286 100644 --- a/infer/src/clang/ALVar.ml +++ b/infer/src/clang/ALVar.ml @@ -72,6 +72,27 @@ let is_mode_keyword k = | Mode -> true | _ -> false +(* true if and only if a substring of container matches the regular + expression defined by contained +*) +let str_match_regex container re = + let rexp = Str.regexp re in + try + Str.search_forward rexp container 0 >= 0 + with Not_found -> false + +let compare_str_with_alexp s ae = + match ae with + | Const s' + | Var s' -> + String.equal s s' + | Regexp re -> + str_match_regex s re + | _ -> + Logging.out "[WARNING]: ALVAR expression '%s' is not a constant/var or regexp\n" + (alexp_to_string ae); + false + module FormulaIdMap = Caml.Map.Make ( struct diff --git a/infer/src/clang/ALVar.mli b/infer/src/clang/ALVar.mli index 283c107a0..cc08c07a6 100644 --- a/infer/src/clang/ALVar.mli +++ b/infer/src/clang/ALVar.mli @@ -43,4 +43,6 @@ val is_severity_keyword : keyword -> bool val is_mode_keyword : keyword -> bool +val compare_str_with_alexp : string -> alexp -> bool + module FormulaIdMap : Caml.Map.S with type key = formula_id diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 3cbe8c19d..e612e914e 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -11,6 +11,8 @@ open! IStd open Lexing open Types_lexer +let parsed_type_map : Ctl_parser_types.abs_ctype String.Map.t ref = ref String.Map.empty + let get_available_attr_ios_sdk an = let open Clang_ast_t in let rec get_available_attr attrs = @@ -60,24 +62,6 @@ let captured_variables_cxx_ref an = type t = ALVar.formula_id * ALVar.alexp list(* (name, [param1,...,paramK]) *) -(* true if and only if a substring of container matches the regular - expression defined by contained -*) -let str_match_regex container re = - let rexp = Str.regexp re in - try - Str.search_forward rexp container 0 >= 0 - with Not_found -> false - -let compare_str_with_alexp s ae = - match ae with - | ALVar.Const s' -> - String.equal s s' - | ALVar.Regexp re -> str_match_regex s re - | _ -> - Logging.out "[WARNING]: ALVAR expression '%s' is not a constant or regexp\n" - (ALVar.alexp_to_string ae); - false let pp_predicate fmt (_name, _arglist) = let name = ALVar.formula_id_to_string _name in @@ -88,7 +72,7 @@ let pp_predicate fmt (_name, _arglist) = let is_objc_interface_named an expected_name = match an with | Ctl_parser_types.Decl Clang_ast_t.ObjCInterfaceDecl(_, ni, _, _, _) -> - compare_str_with_alexp ni.ni_name expected_name + ALVar.compare_str_with_alexp ni.ni_name expected_name | _ -> false (* checkes whether an object is of a certain class *) @@ -108,7 +92,7 @@ let is_object_of_class_named receiver cname = let call_method an m = match an with | Ctl_parser_types.Stmt (Clang_ast_t.ObjCMessageExpr (_, _, _, omei)) -> - compare_str_with_alexp omei.omei_selector m + ALVar.compare_str_with_alexp omei.omei_selector m | _ -> false let is_receiver_kind_class omei cname = @@ -119,7 +103,7 @@ let is_receiver_kind_class omei cname = | Some ObjCInterfaceType (_, ptr) -> (match CAst_utils.get_decl ptr with | Some ObjCInterfaceDecl (_, ndi, _, _, _) -> - compare_str_with_alexp ndi.ni_name cname + ALVar.compare_str_with_alexp ndi.ni_name cname | _ -> false) | _ -> false) | _ -> false @@ -128,7 +112,7 @@ let call_class_method an cname mname = match an with | Ctl_parser_types.Stmt (Clang_ast_t.ObjCMessageExpr (_, _, _, omei)) -> is_receiver_kind_class omei cname && - compare_str_with_alexp omei.omei_selector mname + ALVar.compare_str_with_alexp omei.omei_selector mname | _ -> false (* an is a node calling method whose name contains mname of a @@ -138,7 +122,7 @@ let call_instance_method an cname mname = match an with | Ctl_parser_types.Stmt (Clang_ast_t.ObjCMessageExpr (_, receiver :: _, _, omei)) -> is_object_of_class_named receiver cname && - compare_str_with_alexp omei.omei_selector mname + ALVar.compare_str_with_alexp omei.omei_selector mname | _ -> false let is_objc_extension lcxt = @@ -159,7 +143,7 @@ let decl_ref_name ?kind name st = | Clang_ast_t.DeclRefExpr (_, _, _, drti) -> (match drti.drti_decl_ref with | Some dr -> let ndi, _, _ = CAst_utils.get_info_from_decl_ref dr in - let has_right_name = compare_str_with_alexp ndi.ni_name name in + let has_right_name = ALVar.compare_str_with_alexp ndi.ni_name name in (match kind with | Some decl_kind -> has_right_name && PVariant.(=) dr.Clang_ast_t.dr_kind decl_kind @@ -271,7 +255,7 @@ let is_binop_with_kind an alexp_kind = failwith ("Binary operator kind " ^ str_kind ^ " is not valid"); match an with | Ctl_parser_types.Stmt (Clang_ast_t.BinaryOperator (_, _, _, boi)) -> - compare_str_with_alexp (Clang_ast_proj.string_of_binop_kind boi.boi_kind) alexp_kind + ALVar.compare_str_with_alexp (Clang_ast_proj.string_of_binop_kind boi.boi_kind) alexp_kind | _ -> false let is_unop_with_kind an alexp_kind = @@ -280,7 +264,7 @@ let is_unop_with_kind an alexp_kind = failwith ("Unary operator kind " ^ str_kind ^ " is not valid"); match an with | Ctl_parser_types.Stmt (Clang_ast_t.UnaryOperator (_, _, _, uoi)) -> - compare_str_with_alexp (Clang_ast_proj.string_of_unop_kind uoi.uoi_kind) alexp_kind + ALVar.compare_str_with_alexp (Clang_ast_proj.string_of_unop_kind uoi.uoi_kind) alexp_kind | _ -> false let is_node an nodename = @@ -290,7 +274,7 @@ let is_node an nodename = let an_str = match an with | Ctl_parser_types.Stmt s -> Clang_ast_proj.get_stmt_kind_string s | Ctl_parser_types.Decl d -> Clang_ast_proj.get_decl_kind_string d in - compare_str_with_alexp an_str nodename + ALVar.compare_str_with_alexp an_str nodename let is_ptr_to_objc_class typ class_name = match typ with @@ -299,7 +283,7 @@ let is_ptr_to_objc_class typ class_name = | Some ObjCInterfaceType (_, ptr) -> (match CAst_utils.get_decl ptr with | Some ObjCInterfaceDecl (_, ndi, _, _, _) -> - compare_str_with_alexp ndi.ni_name class_name + ALVar.compare_str_with_alexp ndi.ni_name class_name | _ -> false) | _ -> false) | _ -> false @@ -320,7 +304,7 @@ let declaration_has_name an name = match an with | Ctl_parser_types.Decl d -> (match Clang_ast_proj.get_named_decl_tuple d with - | Some (_, ndi) -> compare_str_with_alexp ndi.ni_name name + | Some (_, ndi) -> ALVar.compare_str_with_alexp ndi.ni_name name | _ -> false) | _ -> false @@ -352,8 +336,10 @@ let type_ptr_equal_type type_ptr type_str = let pos = lexbuf.lex_curr_p in pos.pos_fname ^ ":" ^ (string_of_int pos.pos_lnum) ^ ":" ^ (string_of_int (pos.pos_cnum - pos.pos_bol + 1)) in - let lexbuf = Lexing.from_string type_str in - let abs_ctype = try + + let parse_type_string str = + let lexbuf = Lexing.from_string str in + try (Types_parser.abs_ctype token lexbuf) with | Ctl_parser_types.ALParsingException s -> @@ -362,10 +348,16 @@ let type_ptr_equal_type type_ptr type_str = | SyntaxError _ | Types_parser.Error -> raise (Ctl_parser_types.ALParsingException - ("SYNTAX ERROR at " ^ (pos_str lexbuf))) in + ("SYNTAX ERROR at " ^ (pos_str lexbuf))) in + let abs_ctype = + match String.Map.find !parsed_type_map type_str with + | Some abs_ctype' -> abs_ctype' + | None -> let abs_ctype' = parse_type_string type_str in + parsed_type_map := String.Map.add !parsed_type_map ~key:type_str ~data:abs_ctype'; + abs_ctype' in match CAst_utils.get_type type_ptr with | Some c_type' -> - Ctl_parser_types.tmp_c_type_equal c_type' abs_ctype + Ctl_parser_types.c_type_equal c_type' abs_ctype | _ -> Logging.out "Couldn't find type....\n"; false let has_type an _typ = diff --git a/infer/src/clang/ctl_parser_types.ml b/infer/src/clang/ctl_parser_types.ml index 8eb41faa7..1695bb5e0 100644 --- a/infer/src/clang/ctl_parser_types.ml +++ b/infer/src/clang/ctl_parser_types.ml @@ -116,17 +116,72 @@ let builtin_kind_to_string t = type abs_ctype = | BuiltIn of builtin_kind | Pointer of abs_ctype + | TypeName of ALVar.alexp +let display_equality_warning () = + Logging.out + "[WARNING:] Type Comparison failed... \ + This might indicate that the types are different or the specified type \ + is internally represented in a different way and therefore not recognized.\n" let rec abs_ctype_to_string t = match t with | BuiltIn t' -> "BuiltIn (" ^ (builtin_kind_to_string t') ^ ")" | Pointer t' -> "Pointer (" ^ (abs_ctype_to_string t') ^ ")" + | TypeName ae -> "TypeName (" ^ (ALVar.alexp_to_string ae) ^ ")" + + +let builtin_equal bi abi = + match bi, abi with + | `Char_U, Char_U + | `Char_S, Char_U + | `Char16, Char16 + | `Char32, Char32 + | `WChar_U, WChar_U + | `WChar_S, WChar_U + | `Bool, Bool + | `Short, Short + | `Int, Int + | `Long, Long + | `Float, Float + | `Double, Double + | `Void, Void + | `SChar, SChar + | `LongLong, LongLong + | `UChar, UChar + | `UShort, UShort + | `UInt, UInt + | `ULong, ULong + | `ULongLong, ULongLong + | `LongDouble, LongDouble + | `Int128, Int128 + | `UInt128, UInt128 + | `Float128, Float128 + | `NullPtr, NullPtr + | `ObjCId, ObjCId + | `ObjCClass, ObjCClass + | `ObjCSel, ObjCSel + | `Half, Half -> true + | _, _ -> display_equality_warning (); + false + +let rec pointer_type_equal p ap = + let open Clang_ast_t in + match p, ap with + | PointerType (_, qt), Pointer abs_ctype' + | ObjCObjectPointerType (_, qt), Pointer abs_ctype' -> + (match CAst_utils.get_type qt.qt_type_ptr with + | Some c_type' -> + c_type_equal c_type' abs_ctype' + | None -> false) + | _, _ -> display_equality_warning (); + false + (* Temporary, partial equality function. Cover only what's covered by the types_parser. It needs to be replaced by a real comparison function for Clang_ast_t.c_type *) -let rec tmp_c_type_equal c_type abs_ctype = +and c_type_equal c_type abs_ctype = Logging.out "Comparing c_type/abs_ctype for equality... \ Type compared: \nc_type = `%s` \nabs_ctype =`%s`\n" @@ -134,45 +189,19 @@ let rec tmp_c_type_equal c_type abs_ctype = (abs_ctype_to_string abs_ctype); let open Clang_ast_t in match c_type, abs_ctype with - | BuiltinType (_ , `Char_U), BuiltIn (Char_U) - | BuiltinType (_ , `Char_S), BuiltIn (Char_U) - | BuiltinType (_, `Char16), BuiltIn (Char16) - | BuiltinType (_, `Char32), BuiltIn (Char32) - | BuiltinType (_, `WChar_U), BuiltIn (WChar_U) - | BuiltinType (_, `WChar_S), BuiltIn (WChar_U) - | BuiltinType (_, `Bool), BuiltIn (Bool) - | BuiltinType (_, `Short), BuiltIn (Short) - | BuiltinType (_, `Int), BuiltIn (Int) - | BuiltinType (_, `Long), BuiltIn (Long) - | BuiltinType (_, `Float), BuiltIn (Float) - | BuiltinType (_, `Double), BuiltIn (Double) - | BuiltinType (_, `Void), BuiltIn (Void) - | BuiltinType (_, `SChar), BuiltIn (SChar) - | BuiltinType (_, `LongLong), BuiltIn (LongLong) - | BuiltinType (_, `UChar), BuiltIn (UChar) - | BuiltinType (_, `UShort), BuiltIn (UShort) - | BuiltinType (_, `UInt), BuiltIn (UInt) - | BuiltinType (_, `ULong), BuiltIn (ULong) - | BuiltinType (_, `ULongLong), BuiltIn (ULongLong) - | BuiltinType (_, `LongDouble), BuiltIn (LongDouble) - | BuiltinType (_, `Int128), BuiltIn (Int128) - | BuiltinType (_, `UInt128), BuiltIn (UInt128) - | BuiltinType (_, `Float128), BuiltIn (Float128) - | BuiltinType (_, `NullPtr), BuiltIn (NullPtr) - | BuiltinType (_, `ObjCId), BuiltIn (ObjCId) - | BuiltinType (_, `ObjCClass), BuiltIn (ObjCClass) - | BuiltinType (_, `ObjCSel), BuiltIn (ObjCSel) - | BuiltinType (_, `Half), BuiltIn (Half) -> true - | PointerType (_, qt), Pointer abs_ctype' -> - (match CAst_utils.get_type qt.qt_type_ptr with - | Some c_type' -> - tmp_c_type_equal c_type' abs_ctype' - | None -> false) - | _, _ -> - Logging.out - "[WARNING:] Type Comparison failed... \ - This might indicate that the types are different or the specified type \ - is internally represented in a different way and therefore not recognized.\n"; + | BuiltinType (_ , bi), BuiltIn abi -> + builtin_equal bi abi + | PointerType _, Pointer _ + | ObjCObjectPointerType _, Pointer _ -> + pointer_type_equal c_type abs_ctype + | ObjCInterfaceType (_, pointer), TypeName ae -> + (match CAst_utils.get_decl pointer with + | Some decl -> + (match Clang_ast_proj.get_named_decl_tuple decl with + | Some (_, name_decl) -> ALVar.compare_str_with_alexp name_decl.ni_name ae + | None -> false) + | _ -> false) + | _, _ -> display_equality_warning (); false (* to be extended with more types *) diff --git a/infer/src/clang/ctl_parser_types.mli b/infer/src/clang/ctl_parser_types.mli index c25a444a3..0ef7cee86 100644 --- a/infer/src/clang/ctl_parser_types.mli +++ b/infer/src/clang/ctl_parser_types.mli @@ -64,7 +64,8 @@ type builtin_kind = type abs_ctype = | BuiltIn of builtin_kind | Pointer of abs_ctype + | TypeName of ALVar.alexp -val tmp_c_type_equal : Clang_ast_t.c_type -> abs_ctype -> bool +val c_type_equal : Clang_ast_t.c_type -> abs_ctype -> bool val abs_ctype_to_string : abs_ctype -> string diff --git a/infer/src/clang/types_lexer.mll b/infer/src/clang/types_lexer.mll index 8bac92182..ef1749fb3 100644 --- a/infer/src/clang/types_lexer.mll +++ b/infer/src/clang/types_lexer.mll @@ -54,5 +54,23 @@ rule token = parse | "Class" { OBJCCLASS } | "SEL" { OBJCSEL } | "*" { STAR } + | "REGEXP" { REGEXP } + | "(" { LEFT_PAREN } + | ")" { RIGHT_PAREN } + | id { IDENTIFIER (Lexing.lexeme lexbuf) } + | ''' { read_string (Buffer.create 80) lexbuf } | _ { raise (SyntaxError ("Unexpected char: '" ^ (Lexing.lexeme lexbuf) ^"'")) } | eof { EOF } + + and read_string buf = parse + | ''' { REARG (Buffer.contents buf) } + | '\\' '/' { Buffer.add_char buf '/'; read_string buf lexbuf } + | '\\' '\\' { Buffer.add_char buf '\\'; read_string buf lexbuf } + | '\\' 'b' { Buffer.add_char buf '\b'; read_string buf lexbuf } + | '\\' 'f' { Buffer.add_char buf '\012'; read_string buf lexbuf } + | '\\' 'n' { Buffer.add_char buf '\n'; read_string buf lexbuf } + | '\\' 'r' { Buffer.add_char buf '\r'; read_string buf lexbuf } + | '\\' 't' { Buffer.add_char buf '\t'; read_string buf lexbuf } + | [^ '\'' '\\']+ { Buffer.add_string buf (Lexing.lexeme lexbuf); read_string buf lexbuf } + | _ { raise (SyntaxError ("Illegal string character: " ^ Lexing.lexeme lexbuf)) } + | eof { raise (SyntaxError ("String is not terminated")) } diff --git a/infer/src/clang/types_parser.mly b/infer/src/clang/types_parser.mly index 8d6260b6a..6d28757a8 100644 --- a/infer/src/clang/types_parser.mly +++ b/infer/src/clang/types_parser.mly @@ -54,7 +54,12 @@ %token OBJCSEL %token STAR %token EOF - +%token REGEXP +%token LEFT_PAREN +%token RIGHT_PAREN +%token IDENTIFIER +%token STRING +%token REARG %start abs_ctype %% @@ -69,13 +74,18 @@ abs_ctype: ctype_specifier_seq: | noptr_type_spec { $1 } | ptr_type_spec { $1 } +| type_name { $1 } ; ptr_type_spec: | noptr_type_spec STAR { Pointer $1 } | ptr_type_spec STAR { Pointer $1 } +| type_name STAR { Pointer $1 } ; +type_name: + | alexp { TypeName $1 } + noptr_type_spec: | trailing_type_specifier_seq { let atyp = tokens_to_abs_types $1 in @@ -117,4 +127,13 @@ simple_type_specifier: | OBJCSEL { ObjCSel } ; + alexp: + | STRING { Logging.out "\tParsed string constant '%s' \n" $1; + ALVar.Const $1 } + | REGEXP LEFT_PAREN REARG RIGHT_PAREN + { Logging.out "\tParsed regular expression '%s' \n" $3; + ALVar.Regexp $3 } + | IDENTIFIER { ALVar.Var $1 } + ; + %% 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 88e61f301..9fd5c7cd0 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -29,24 +29,26 @@ codetoanalyze/objc/linters-for-test-only/subclassing.m, Linters_dummy_method, 53 codetoanalyze/objc/linters-for-test-only/subclassing.m, Linters_dummy_method, 53, IMPORTED_MACRO_SUBCLASS, [] codetoanalyze/objc/linters-for-test-only/subclassing.m, Linters_dummy_method, 53, LOCAL_MACRO_SUBCLASS, [] codetoanalyze/objc/linters-for-test-only/subclassing.m, Linters_dummy_method, 53, SUBCLASSING_TEST_EXAMPLE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m1, 67, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m10, 76, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m11, 77, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m12, 78, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m13, 79, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m14, 80, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m15, 81, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m15, 81, TEST_RETURN_METHOD, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m16, 82, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m17, 83, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m2, 68, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m20, 85, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m21, 86, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m22, 87, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m23, 93, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m24, 94, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m3, 69, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m4, 70, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m7, 73, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m8, 74, TEST_BUILTIN_TYPE, [] -codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m9, 75, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m1, 73, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m10, 82, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m11, 83, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m12, 84, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m13, 85, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m14, 86, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m15, 87, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m15, 87, TEST_RETURN_METHOD, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m16, 88, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m17, 89, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m2, 74, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m20, 91, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m21, 92, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m22, 93, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m23, 99, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m24, 100, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m25, 101, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m26, 102, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m3, 75, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m4, 76, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m7, 79, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m8, 80, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m9, 81, TEST_BUILTIN_TYPE, [] 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 0c14cd2b1..3405cf17f 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 @@ -126,6 +126,8 @@ DEFINE-CHECKER TEST_BUILTIN_TYPE = { OR method_return_type("SEL") OR method_return_type("float *") OR method_return_type("unsigned int **") + OR method_return_type("A*") + OR method_return_type("REGEXP('This.+')*" ) HOLDS-IN-NODE ObjCMethodDecl; SET message = "Method return....."; diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/subclassing.m b/infer/tests/codetoanalyze/objc/linters-for-test-only/subclassing.m index 15bde9839..cb8a0e6ce 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/subclassing.m +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/subclassing.m @@ -62,6 +62,12 @@ @implementation F @end +@interface ThisIsAVeryLongName : NSObject +@end + +@implementation ThisIsAVeryLongName +@end + @interface TestType : NSObject - (void)m1; @@ -92,5 +98,6 @@ //- (SEL) m27; - (float*)m23; - (unsigned int**)m24; - +- (A*)m25; +- (ThisIsAVeryLongName*)m26; @end