diff --git a/infer/src/absint/annotations.ml b/infer/src/absint/annotations.ml index 9934f2eea..d7945a4c8 100644 --- a/infer/src/absint/annotations.ml +++ b/infer/src/absint/annotations.ml @@ -158,10 +158,6 @@ let pdesc_get_return_annot pdesc = let pdesc_has_return_annot pdesc predicate = predicate (pdesc_get_return_annot pdesc) -let pdesc_return_annot_ends_with pdesc annot = - pdesc_has_return_annot pdesc (fun ia -> ia_ends_with ia annot) - - let pname_has_return_annot pname predicate = match Attributes.load pname with | Some attributes -> @@ -170,6 +166,10 @@ let pname_has_return_annot pname predicate = false +let attrs_return_annot_ends_with attrs annot = + ia_ends_with attrs.ProcAttributes.method_annotation.return annot + + let field_has_annot fieldname (struct_typ : Struct.t) predicate = let fld_has_taint_annot (fname, _, annot) = Fieldname.equal fieldname fname && predicate annot in List.exists ~f:fld_has_taint_annot struct_typ.fields diff --git a/infer/src/absint/annotations.mli b/infer/src/absint/annotations.mli index 167f287dc..795510e64 100644 --- a/infer/src/absint/annotations.mli +++ b/infer/src/absint/annotations.mli @@ -124,8 +124,8 @@ val pdesc_has_return_annot : Procdesc.t -> (Annot.Item.t -> bool) -> bool val pname_has_return_annot : Procname.t -> (Annot.Item.t -> bool) -> bool (** return true if the given predicate evaluates to true on the annotation of [pname]'s return value *) -val pdesc_return_annot_ends_with : Procdesc.t -> string -> bool -(** return true if [pdesc]'s return value is annotated with a value ending with the given string *) +val attrs_return_annot_ends_with : ProcAttributes.t -> string -> bool +(** return true if return value in [attrs] is annotated with a value ending with the given string *) val ma_has_annotation_with : Annot.Method.t -> (Annot.t -> bool) -> bool diff --git a/infer/src/concurrency/RacerDFileAnalysis.ml b/infer/src/concurrency/RacerDFileAnalysis.ml index 44211029d..f58771e23 100644 --- a/infer/src/concurrency/RacerDFileAnalysis.ml +++ b/infer/src/concurrency/RacerDFileAnalysis.ml @@ -623,31 +623,33 @@ let make_results_table exe_env summaries = aggregate_post tenv procname acc summary ) -let should_report_on_proc file_exe_env procdesc = - let proc_name = Procdesc.get_proc_name procdesc in - let tenv = Exe_env.get_proc_tenv file_exe_env proc_name in - match proc_name with - | CSharp _ -> - not (ProcAttributes.equal_access (Procdesc.get_access procdesc) Private) - | Java java_pname -> - (* return true if procedure is at an abstraction boundary or reporting has been explicitly - requested via @ThreadSafe in java *) - RacerDModels.is_thread_safe_method proc_name tenv - || (not (ProcAttributes.equal_access (Procdesc.get_access procdesc) Private)) - && (not (Procname.Java.is_class_initializer java_pname)) - && (not (Procname.Java.is_autogen_method java_pname)) - && not (Annotations.pdesc_return_annot_ends_with procdesc Annotations.visibleForTesting) - | ObjC_Cpp _ when Procname.is_cpp_lambda proc_name -> - (* do not report on lambdas; they are essentially private though do not appear as such *) - false - | ObjC_Cpp {kind= CPPMethod _ | CPPConstructor _ | CPPDestructor _} -> - not (ProcAttributes.equal_access (Procdesc.get_access procdesc) Private) - | ObjC_Cpp {kind= ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod; class_name} -> - Tenv.lookup tenv class_name - |> Option.exists ~f:(fun {Struct.exported_objc_methods} -> - List.mem ~equal:Procname.equal exported_objc_methods proc_name ) - | _ -> - false +let should_report_on_proc file_exe_env proc_name = + Attributes.load proc_name + |> Option.exists ~f:(fun attrs -> + let tenv = Exe_env.get_proc_tenv file_exe_env proc_name in + let is_not_private = not ProcAttributes.(equal_access (get_access attrs) Private) in + match (proc_name : Procname.t) with + | CSharp _ -> + is_not_private + | Java java_pname -> + (* return true if procedure is at an abstraction boundary or reporting has been explicitly + requested via @ThreadSafe in java *) + RacerDModels.is_thread_safe_method proc_name tenv + || is_not_private + && (not (Procname.Java.is_class_initializer java_pname)) + && (not (Procname.Java.is_autogen_method java_pname)) + && not Annotations.(attrs_return_annot_ends_with attrs visibleForTesting) + | ObjC_Cpp _ when Procname.is_cpp_lambda proc_name -> + (* do not report on lambdas; they are essentially private though do not appear as such *) + false + | ObjC_Cpp {kind= CPPMethod _ | CPPConstructor _ | CPPDestructor _} -> + is_not_private + | ObjC_Cpp {kind= ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod; class_name} -> + Tenv.lookup tenv class_name + |> Option.exists ~f:(fun {Struct.exported_objc_methods} -> + List.mem ~equal:Procname.equal exported_objc_methods proc_name ) + | _ -> + false ) let class_has_concurrent_method class_summaries = @@ -675,7 +677,7 @@ let aggregate_by_class {InterproceduralAnalysis.procedures; file_exe_env; analyz Procname.get_class_type_name procname |> Option.bind ~f:(fun classname -> analyze_file_dependency procname - |> Option.filter ~f:(fun (pdesc, _) -> should_report_on_proc file_exe_env pdesc) + |> Option.filter ~f:(fun _ -> should_report_on_proc file_exe_env procname) |> Option.map ~f:(fun summary_proc_desc -> Typ.Name.Map.update classname (function