diff --git a/infer/src/checkers/annotations.mli b/infer/src/checkers/annotations.mli index e61c85d2b..a3c2a929c 100644 --- a/infer/src/checkers/annotations.mli +++ b/infer/src/checkers/annotations.mli @@ -37,8 +37,6 @@ val guarded_by : string val suppress_lint : string -val thread_confined : string - val thread_safe : string val mainthread : string diff --git a/infer/src/concurrency/RacerD.ml b/infer/src/concurrency/RacerD.ml index a17604858..f1b643304 100644 --- a/infer/src/concurrency/RacerD.ml +++ b/infer/src/concurrency/RacerD.ml @@ -11,6 +11,8 @@ module F = Format module L = Logging module MF = MarkupFormatter +let attrs_of_pname = Summary.OnDisk.proc_resolve_attributes + module Payload = SummaryPayload.Make (struct type t = RacerDDomain.summary @@ -505,14 +507,14 @@ let analyze_procedure {Callbacks.exe_env; summary} = Typ.Procname.is_constructor proc_name || FbThreadSafety.is_custom_init tenv proc_name in let open RacerDDomain in - if should_analyze_proc proc_desc tenv then + if should_analyze_proc tenv proc_name then let formal_map = FormalMap.make proc_desc in let proc_data = ProcData.make summary tenv ProcData.empty_extras in let initial = let threads = if - runs_on_ui_thread ~attrs_of_pname:Summary.OnDisk.proc_resolve_attributes tenv proc_name - || is_thread_confined_method tenv proc_desc + runs_on_ui_thread ~attrs_of_pname tenv proc_name + || is_thread_confined_method tenv proc_name then ThreadsDomain.AnyThreadButSelf else if Procdesc.is_java_synchronized proc_desc || is_marked_thread_safe proc_name tenv then ThreadsDomain.AnyThread diff --git a/infer/src/concurrency/RacerDModels.ml b/infer/src/concurrency/RacerDModels.ml index d436fe527..0d17c956c 100644 --- a/infer/src/concurrency/RacerDModels.ml +++ b/infer/src/concurrency/RacerDModels.ml @@ -266,11 +266,10 @@ let is_box = function methods at all. In future we should account for races between these methods and methods from completely different classes that don't necessarily run on the same thread as the confined object. *) -(* FIXME use ConcurrencyModels.find_override_or_superclass_annotated *) -let is_thread_confined_method tenv pdesc = - Annotations.pdesc_return_annot_ends_with pdesc Annotations.thread_confined - || PatternMatch.check_current_class_attributes Annotations.ia_is_thread_confined tenv - (Procdesc.get_proc_name pdesc) +let is_thread_confined_method tenv pname = + ConcurrencyModels.find_override_or_superclass_annotated ~attrs_of_pname + Annotations.ia_is_thread_confined tenv pname + |> Option.is_some let threadsafe_annotations = @@ -310,19 +309,17 @@ let is_assumed_thread_safe item_annot = List.exists ~f item_annot -(* FIXME use ConcurrencyModels.find_override_or_superclass_annotated *) -let pdesc_is_assumed_thread_safe pdesc tenv = - is_assumed_thread_safe (Annotations.pdesc_get_return_annot pdesc) - || PatternMatch.check_current_class_attributes is_assumed_thread_safe tenv - (Procdesc.get_proc_name pdesc) +let is_assumed_thread_safe tenv pname = + ConcurrencyModels.find_override_or_superclass_annotated ~attrs_of_pname is_assumed_thread_safe + tenv pname + |> Option.is_some (* return true if we should compute a summary for the procedure. if this returns false, we won't analyze the procedure or report any warnings on it *) (* note: in the future, we will want to analyze the procedures in all of these cases in order to find more bugs. this is just a temporary measure to avoid obvious false positives *) -let should_analyze_proc pdesc tenv = - let pn = Procdesc.get_proc_name pdesc in +let should_analyze_proc tenv pn = (not ( match pn with | Typ.Procname.Java java_pname -> @@ -332,7 +329,7 @@ let should_analyze_proc pdesc tenv = | _ -> false )) && (not (FbThreadSafety.is_logging_method pn)) - && (not (pdesc_is_assumed_thread_safe pdesc tenv)) + && (not (is_assumed_thread_safe tenv pn)) && not (should_skip pn) @@ -350,7 +347,6 @@ let is_thread_safe_method pname tenv = let is_marked_thread_safe pname tenv = ((* current class not marked [@NotThreadSafe] *) - (* FIXME use ConcurrencyModels.find_override_or_superclass_annotated *) not (PatternMatch.check_current_class_attributes Annotations.ia_is_not_thread_safe tenv pname)) && ConcurrencyModels.find_override_or_superclass_annotated ~attrs_of_pname is_thread_safe tenv @@ -410,9 +406,9 @@ let should_flag_interface_call tenv exps call_flags pname = && (not (is_builder_function java_pname)) (* can't ask anyone to annotate interfaces in library code, and Builders should always be thread-safe (would be unreasonable to ask everyone to annotate them) *) - (* FIXME use ConcurrencyModels.find_override_or_superclass_annotated for the two cases below *) - && (not (PatternMatch.check_class_attributes thread_safe_or_thread_confined tenv pname)) - && (not (has_return_annot thread_safe_or_thread_confined pname)) + && ConcurrencyModels.find_override_or_superclass_annotated ~attrs_of_pname + thread_safe_or_thread_confined tenv pname + |> Option.is_none && receiver_is_not_safe exps tenv && not (implements_threadsafe_interface java_pname tenv) | _ -> @@ -423,8 +419,7 @@ let is_synchronized_container callee_pname (access_exp : HilExp.AccessExpression let is_threadsafe_collection pn tenv = match pn with | Typ.Procname.Java java_pname -> - (* FIXME use get_class_type_name *) - let typename = Typ.Name.Java.from_string (Typ.Procname.Java.get_class_name java_pname) in + let typename = Typ.Procname.Java.get_class_type_name java_pname in let aux tn _ = match Typ.Name.name tn with | "java.util.concurrent.ConcurrentMap" diff --git a/infer/src/concurrency/RacerDModels.mli b/infer/src/concurrency/RacerDModels.mli index 89b0c90d7..2aef5ff12 100644 --- a/infer/src/concurrency/RacerDModels.mli +++ b/infer/src/concurrency/RacerDModels.mli @@ -21,14 +21,14 @@ val acquires_ownership : Typ.Procname.t -> Tenv.t -> bool val is_box : Typ.Procname.t -> bool (** return true if the given procname boxes a primitive type into a reference type *) -val is_thread_confined_method : Tenv.t -> Procdesc.t -> bool +val is_thread_confined_method : Tenv.t -> Typ.Procname.t -> bool (** Methods in @ThreadConfined classes and methods annotated with @ThreadConfined are assumed to all run on the same thread. For the moment we won't warn on accesses resulting from use of such methods at all. In future we should account for races between these methods and methods from completely different classes that don't necessarily run on the same thread as the confined object. *) -val should_analyze_proc : Procdesc.t -> Tenv.t -> bool +val should_analyze_proc : Tenv.t -> Typ.Procname.t -> bool (** return true if we should compute a summary for the procedure. if this returns false, we won't analyze the procedure or report any warnings on it. note: in the future, we will want to analyze the procedures in all of these cases in order to