diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index c6d5c0615..3cbe8c19d 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -354,7 +354,7 @@ let type_ptr_equal_type type_ptr type_str = (string_of_int (pos.pos_cnum - pos.pos_bol + 1)) in let lexbuf = Lexing.from_string type_str in let abs_ctype = try - (Types_parser.ctype_specifier_seq token lexbuf) + (Types_parser.abs_ctype token lexbuf) with | Ctl_parser_types.ALParsingException s -> raise (Ctl_parser_types.ALParsingException @@ -365,8 +365,7 @@ let type_ptr_equal_type type_ptr type_str = ("SYNTAX ERROR at " ^ (pos_str lexbuf))) in match CAst_utils.get_type type_ptr with | Some c_type' -> - let name = Clang_ast_extend.type_ptr_to_string type_ptr in - Ctl_parser_types.tmp_c_type_equal ~name_c_type:name c_type' abs_ctype + Ctl_parser_types.tmp_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 f098b62a7..d64dab5ef 100644 --- a/infer/src/clang/ctl_parser_types.ml +++ b/infer/src/clang/ctl_parser_types.ml @@ -115,15 +115,23 @@ let builtin_kind_to_string t = type abs_ctype = | BuiltIn of builtin_kind + | Pointer of abs_ctype -let abs_ctype_to_string t = + +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') ^ ")" (* 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 tmp_c_type_equal ?name_c_type c_type abs_ctype = +let rec tmp_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" + (Clang_ast_j.string_of_c_type c_type) + (abs_ctype_to_string abs_ctype); let open Clang_ast_t in match c_type, abs_ctype with | BuiltinType (_ , `Char_U), BuiltIn (Char_U) @@ -155,16 +163,16 @@ let tmp_c_type_equal ?name_c_type c_type abs_ctype = | 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) | _, _ -> - let name = (match name_c_type with - | None -> "" - | Some n -> n) in 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. \ - Type compared: c_type = `%s` abs_ctype =`%s`\n" - name (abs_ctype_to_string abs_ctype); + is internally represented in a different way and therefore not recognized.\n"; false (* to be extended with more types *) diff --git a/infer/src/clang/types_lexer.mll b/infer/src/clang/types_lexer.mll index d10a365d3..8bac92182 100644 --- a/infer/src/clang/types_lexer.mll +++ b/infer/src/clang/types_lexer.mll @@ -53,5 +53,6 @@ rule token = parse | "id" { OBJCID } | "Class" { OBJCCLASS } | "SEL" { OBJCSEL } + | "*" { STAR } | _ { raise (SyntaxError ("Unexpected char: '" ^ (Lexing.lexeme lexbuf) ^"'")) } | eof { EOF } diff --git a/infer/src/clang/types_parser.mly b/infer/src/clang/types_parser.mly index 3817ffe65..8d6260b6a 100644 --- a/infer/src/clang/types_parser.mly +++ b/infer/src/clang/types_parser.mly @@ -52,27 +52,45 @@ %token OBJCID %token OBJCCLASS %token OBJCSEL +%token STAR %token EOF -%start ctype_specifier_seq +%start abs_ctype %% +abs_ctype: + | ctype_specifier_seq EOF { + Logging.out "\tType effectively parsed: `%s`\n" + (Ctl_parser_types.abs_ctype_to_string $1); + $1 } + ; + ctype_specifier_seq: - | trailing_type_specifier_seq EOF +| noptr_type_spec { $1 } +| ptr_type_spec { $1 } +; + +ptr_type_spec: +| noptr_type_spec STAR { Pointer $1 } +| ptr_type_spec STAR { Pointer $1 } +; + +noptr_type_spec: + | trailing_type_specifier_seq { let atyp = tokens_to_abs_types $1 in - Logging.out "\tParsed `%s`\n" (Ctl_parser_types.abs_ctype_to_string atyp); atyp } + ; trailing_type_specifier: | simple_type_specifier { $1 } - + ; trailing_type_specifier_seq: | trailing_type_specifier { [$1] } - | simple_type_specifier trailing_type_specifier_seq { $1 :: $2 } - + | trailing_type_specifier trailing_type_specifier_seq { $1 :: $2 } + ; simple_type_specifier: | CHAR { Char_U } 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 eb46c4eb2..88e61f301 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -43,6 +43,8 @@ codetoanalyze/objc/linters-for-test-only/subclassing.m, TestType_m2, 68, TEST_BU 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, [] 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 70135b4de..0c14cd2b1 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 @@ -124,6 +124,8 @@ DEFINE-CHECKER TEST_BUILTIN_TYPE = { OR method_return_type("id") OR method_return_type("Class") OR method_return_type("SEL") + OR method_return_type("float *") + OR method_return_type("unsigned int **") 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 450f4e53e..15bde9839 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/subclassing.m +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/subclassing.m @@ -90,5 +90,7 @@ //- (id) m25; //- (Class) m26; //- (SEL) m27; +- (float*)m23; +- (unsigned int**)m24; @end