[biabduction] Add to the skip reason when the method comes from a protocol

Reviewed By: jvillard

Differential Revision: D7877741

fbshipit-source-id: 5c5d8fd
master
Dulma Churchill 7 years ago committed by Facebook Github Bot
parent bc6afc5d32
commit c24ff02bb4

@ -359,6 +359,8 @@ module Name = struct
let is_class = function CppClass _ | JavaClass _ | ObjcClass _ -> true | _ -> false let is_class = function CppClass _ | JavaClass _ | ObjcClass _ -> true | _ -> false
let is_objc_protocol name = match name with ObjcProtocol _ -> true | _ -> false
let is_same_type t1 t2 = let is_same_type t1 t2 =
match (t1, t2) with match (t1, t2) with
| CStruct _, CStruct _ | CStruct _, CStruct _
@ -878,6 +880,10 @@ module Procname = struct
t t
let is_method_in_objc_protocol t =
match t with ObjC_Cpp osig -> Name.is_objc_protocol osig.class_name | _ -> false
let rec objc_cpp_replace_method_name t (new_method_name: string) = let rec objc_cpp_replace_method_name t (new_method_name: string) =
match t with match t with
| ObjC_Cpp osig -> | ObjC_Cpp osig ->

@ -508,6 +508,8 @@ module Procname : sig
(** Replace the class name component of a procedure name. (** Replace the class name component of a procedure name.
In case of Java, replace package and class name. *) In case of Java, replace package and class name. *)
val is_method_in_objc_protocol : t -> bool
val to_string : t -> string val to_string : t -> string
(** Convert a proc name to a string for the user to see. *) (** Convert a proc name to a string for the user to see. *)

@ -358,13 +358,22 @@ let check_inherently_dangerous_function caller_pname callee_pname =
Reporting.log_warning_deprecated caller_pname exn Reporting.log_warning_deprecated caller_pname exn
let reason_to_skip callee_summary : string option = let reason_to_skip ~callee_desc : string option =
match callee_desc with
| Some (`Summary callee_summary) ->
let attributes = Specs.get_attributes callee_summary in let attributes = Specs.get_attributes callee_summary in
if attributes.ProcAttributes.is_abstract then Some "abstract method" if attributes.ProcAttributes.is_abstract then Some "abstract method"
else if not attributes.ProcAttributes.is_defined then Some "method has no implementation" else if not attributes.ProcAttributes.is_defined then Some "method has no implementation"
else if List.is_empty (Specs.get_specs_from_payload callee_summary) then else if List.is_empty (Specs.get_specs_from_payload callee_summary) then
Some "empty list of specs" Some "empty list of specs"
else None else (* we are not skipping *) None
| Some (`ProcName callee_pname) ->
(* no summary, so we are skipping, determining reasons *)
if Typ.Procname.is_method_in_objc_protocol callee_pname then
Some "no implementation found for method declared in Objective-C protocol"
else Some "function or method not found"
| None ->
Some "function or method not found"
(** In case of constant string dereference, return the result immediately *) (** In case of constant string dereference, return the result immediately *)
@ -1175,7 +1184,7 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p
let ret_annots = load_ret_annots callee_pname in let ret_annots = load_ret_annots callee_pname in
exec_skip_call ~reason:"unknown method" resolved_pname ret_annots ret_typ exec_skip_call ~reason:"unknown method" resolved_pname ret_annots ret_typ
| Some resolved_summary -> | Some resolved_summary ->
match reason_to_skip resolved_summary with match reason_to_skip ~callee_desc:(Some (`Summary resolved_summary)) with
| None -> | None ->
proc_call exe_env resolved_summary proc_call exe_env resolved_summary
(call_args prop_ callee_pname norm_args ret_id_typ loc) (call_args prop_ callee_pname norm_args ret_id_typ loc)
@ -1201,7 +1210,7 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p
let ret_annots = load_ret_annots callee_pname in let ret_annots = load_ret_annots callee_pname in
exec_skip_call ~reason:"unknown method" ret_annots ret_typ exec_skip_call ~reason:"unknown method" ret_annots ret_typ
| Some callee_summary -> | Some callee_summary ->
match reason_to_skip callee_summary with match reason_to_skip ~callee_desc:(Some (`Summary callee_summary)) with
| None -> | None ->
let handled_args = call_args norm_prop pname url_handled_args ret_id_typ loc in let handled_args = call_args norm_prop pname url_handled_args ret_id_typ loc in
proc_call exe_env callee_summary handled_args proc_call exe_env callee_summary handled_args
@ -1249,11 +1258,14 @@ let rec sym_exec exe_env tenv current_pdesc instr_ (prop_: Prop.normal Prop.t) p
else [(prop_r, path)] else [(prop_r, path)]
in in
let do_call (prop, path) = let do_call (prop, path) =
let reason_to_skip_opt = let callee_desc =
Option.value_map ~f:reason_to_skip ~default:(Some "function or method not found") match resolved_summary_opt with
resolved_summary_opt | Some summary ->
Some (`Summary summary)
| None ->
Some (`ProcName resolved_pname)
in in
match reason_to_skip_opt with match reason_to_skip ~callee_desc with
| Some reason | Some reason
-> ( -> (
let ret_annots = let ret_annots =

@ -284,9 +284,10 @@ and get_record_typename ?tenv decl =
Typ.Name.Cpp.from_qual_name Typ.NoTemplate Typ.Name.Cpp.from_qual_name Typ.NoTemplate
(CAst_utils.get_qualified_name ~linters_mode name_info) (CAst_utils.get_qualified_name ~linters_mode name_info)
| ObjCInterfaceDecl (_, name_info, _, _, _), _ | ObjCInterfaceDecl (_, name_info, _, _, _), _
| ObjCImplementationDecl (_, name_info, _, _, _), _ | ObjCImplementationDecl (_, name_info, _, _, _), _ ->
| ObjCProtocolDecl (_, name_info, _, _, _), _ ->
CAst_utils.get_qualified_name name_info |> Typ.Name.Objc.from_qual_name CAst_utils.get_qualified_name name_info |> Typ.Name.Objc.from_qual_name
| ObjCProtocolDecl (_, name_info, _, _, _), _ ->
CAst_utils.get_qualified_name name_info |> Typ.Name.Objc.protocol_from_qual_name
| ObjCCategoryDecl (_, _, _, _, {odi_class_interface= Some {dr_name}}), _ | ObjCCategoryDecl (_, _, _, _, {odi_class_interface= Some {dr_name}}), _
| ObjCCategoryImplDecl (_, _, _, _, {ocidi_class_interface= Some {dr_name}}), _ -> ( | ObjCCategoryImplDecl (_, _, _, _, {ocidi_class_interface= Some {dr_name}}), _ -> (
match dr_name with match dr_name with

@ -87,7 +87,7 @@ codetoanalyze/objc/errors/npe/skip_method_with_nil_object.m, SkipMethodNilA_test
codetoanalyze/objc/errors/property/main.c, property_main, 3, MEMORY_LEAK, ERROR, [start of procedure property_main(),Skipping aProperty: function or method not found] codetoanalyze/objc/errors/property/main.c, property_main, 3, MEMORY_LEAK, ERROR, [start of procedure property_main(),Skipping aProperty: function or method not found]
codetoanalyze/objc/errors/resource_leaks/Dispatch_sources.m, ProcessContentsOfFile, 35, RESOURCE_LEAK, ERROR, [start of procedure ProcessContentsOfFile(),Taking false branch,Skipping dispatch_get_global_queue(): function or method not found,Skipping dispatch_source_create(): function or method not found,Taking false branch] codetoanalyze/objc/errors/resource_leaks/Dispatch_sources.m, ProcessContentsOfFile, 35, RESOURCE_LEAK, ERROR, [start of procedure ProcessContentsOfFile(),Taking false branch,Skipping dispatch_get_global_queue(): function or method not found,Skipping dispatch_source_create(): function or method not found,Taking false branch]
codetoanalyze/objc/errors/resource_leaks/Dispatch_sources.m, objc_blockProcessContentsOfFile_2, 6, MEMORY_LEAK, ERROR, [start of procedure block,Skipping dispatch_source_get_data(): function or method not found,Taking true branch,Skipping MyProcessFileData(): function or method not found] codetoanalyze/objc/errors/resource_leaks/Dispatch_sources.m, objc_blockProcessContentsOfFile_2, 6, MEMORY_LEAK, ERROR, [start of procedure block,Skipping dispatch_source_get_data(): function or method not found,Taking true branch,Skipping MyProcessFileData(): function or method not found]
codetoanalyze/objc/errors/resource_leaks/ResourceLeakExample.m, NSFileHandle_fileHandleForLoggingAtPath:mode:, 9, RESOURCE_LEAK, ERROR, [start of procedure fileHandleForLoggingAtPath:mode:,Taking true branch,Skipping fileSystemRepresentation: function or method not found,Taking false branch,Taking true branch,Skipping autorelease: function or method not found] codetoanalyze/objc/errors/resource_leaks/ResourceLeakExample.m, NSFileHandle_fileHandleForLoggingAtPath:mode:, 9, RESOURCE_LEAK, ERROR, [start of procedure fileHandleForLoggingAtPath:mode:,Taking true branch,Skipping fileSystemRepresentation: function or method not found,Taking false branch,Taking true branch,Skipping autorelease: no implementation found for method declared in Objective-C protocol]
codetoanalyze/objc/shared/annotations/nonnull_annotations.m, A_test1:, 2, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure test1:,Message child with receiver nil returns nil.] codetoanalyze/objc/shared/annotations/nonnull_annotations.m, A_test1:, 2, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure test1:,Message child with receiver nil returns nil.]
codetoanalyze/objc/shared/annotations/nonnull_annotations.m, A_test3:, 1, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure test3:] codetoanalyze/objc/shared/annotations/nonnull_annotations.m, A_test3:, 1, PARAMETER_NOT_NULL_CHECKED, WARNING, [start of procedure test3:]
codetoanalyze/objc/shared/annotations/nullable_annotations.m, User_otherUserName, 2, NULL_DEREFERENCE, ERROR, [start of procedure otherUserName,Skipping otherUser: function or method not found] codetoanalyze/objc/shared/annotations/nullable_annotations.m, User_otherUserName, 2, NULL_DEREFERENCE, ERROR, [start of procedure otherUserName,Skipping otherUser: function or method not found]

Loading…
Cancel
Save