Skip to content

Commit

Permalink
[annot] Add more details to reported methods
Browse files Browse the repository at this point in the history
Summary: If a method is not annotated directly, but inherits its annotation from a base class method, then print the base method in the report too. Plus also distinguish if a method is annotated "directly" or is modeled as if it was annotated.

Reviewed By: ngorogiannis

Differential Revision: D57618235

fbshipit-source-id: 600a52ee6a828de7a98fd49f32c987c12ebad277
  • Loading branch information
hajduakos authored and facebook-github-bot committed May 22, 2024
1 parent 3858b90 commit 348ad42
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
6 changes: 6 additions & 0 deletions infer/src/absint/PatternMatch.mli
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ val override_exists :
(** Return true if applying the given predicate to an override of [procname] (including [procname]
itself when [check_current_type] is true, which it is by default) returns true. *)

val override_find :
?check_current_type:bool -> (Procname.t -> bool) -> Tenv.t -> Procname.t -> Procname.t option
(** Check if the given predicate to an override of [procname] (including [procname] itself when
[check_current_type] is true, which it is by default) returns true. If yes, return the name of
the override. *)

val override_iter : (Procname.t -> unit) -> Tenv.t -> Procname.t -> unit
(** Apply the given predicate to procname and each override of [procname]. For the moment, this only
works for Java *)
Expand Down
46 changes: 32 additions & 14 deletions infer/src/checkers/annotationReachability.ml
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ let check_attributes check tenv pname =
class_has_attribute || proc_has_attribute


let method_overrides is_annotated tenv pname =
PatternMatch.override_exists (fun pn -> is_annotated tenv pn) tenv pname


let check_modeled_annotation models annot pname =
let method_name = Procname.to_string ~verbosity:FullNameOnly pname in
Option.exists (String.Map.find models annot.Annot.class_name) ~f:(fun methods ->
Expand All @@ -95,8 +91,13 @@ let method_has_annot annot models tenv pname =
else check_attributes has_annot tenv pname || check_modeled_annotation models annot pname


let find_override_with_annot annot models tenv pname =
let is_annotated = method_has_annot annot models in
PatternMatch.override_find (fun pn -> is_annotated tenv pn) tenv pname


let method_overrides_annot annot models tenv pname =
method_overrides (method_has_annot annot models) tenv pname
find_override_with_annot annot models tenv pname |> Option.is_some


let lookup_annotation_calls {InterproceduralAnalysis.analyze_dependency} annot pname =
Expand All @@ -112,6 +113,8 @@ let update_trace loc trace =

let string_of_pname = Procname.to_simplified_string ~withclass:true

let annotation_of_str annot_str = {Annot.class_name= annot_str; parameters= []}

let report_allocation_stack {InterproceduralAnalysis.proc_desc; err_log} src_annot fst_call_loc
trace constructor_pname call_loc =
let pname = Procdesc.get_proc_name proc_desc in
Expand All @@ -135,19 +138,36 @@ let get_issue_type src_annot =
else IssueType.checkers_annotation_reachability_error


let report_annotation_stack ({InterproceduralAnalysis.proc_desc; err_log} as analysis_data)
src_annot snk_annot loc trace snk_pname call_loc =
let report_annotation_stack ({InterproceduralAnalysis.proc_desc; tenv; err_log} as analysis_data)
models src_annot snk_annot loc trace snk_pname call_loc =
let src_pname = Procdesc.get_proc_name proc_desc in
if String.equal snk_annot dummy_constructor_annot then
report_allocation_stack analysis_data src_annot loc trace snk_pname call_loc
else
let get_original_pname annot pname =
find_override_with_annot (annotation_of_str annot) models tenv pname
|> Option.value ~default:pname
in
(* Check if the annotation is inherited from a base class method. *)
let get_details annot pname =
let origin_pname = get_original_pname annot pname in
if Procname.equal origin_pname pname then ""
else Format.asprintf ", inherited from %a" MF.pp_monospaced (string_of_pname origin_pname)
in
(* Check if the annotation is there directly or is modeled. *)
let get_kind annot pname =
let pname = get_original_pname annot pname in
if check_modeled_annotation models (annotation_of_str annot) pname then "modeled as"
else "annotated with"
in
let final_trace = List.rev (update_trace call_loc trace) in
let exp_pname_str = string_of_pname snk_pname in
let description =
Format.asprintf "Method %a (annotated with %a) calls %a (annotated with %a)" MF.pp_monospaced
Format.asprintf "Method %a (%s %a%s) calls %a (%s %a%s)" MF.pp_monospaced
(Procname.to_simplified_string src_pname)
MF.pp_monospaced ("@" ^ src_annot) MF.pp_monospaced exp_pname_str MF.pp_monospaced
("@" ^ snk_annot)
(get_kind src_annot src_pname) MF.pp_monospaced ("@" ^ src_annot)
(get_details src_annot src_pname) MF.pp_monospaced (string_of_pname snk_pname)
(get_kind snk_annot snk_pname) MF.pp_monospaced ("@" ^ snk_annot)
(get_details snk_annot snk_pname)
in
let issue_type = get_issue_type src_annot in
Reporting.log_issue proc_desc err_log ~loc ~ltr:final_trace AnnotationReachability issue_type
Expand Down Expand Up @@ -197,7 +217,7 @@ let report_src_snk_path ({InterproceduralAnalysis.proc_desc; tenv; err_log} as a
if method_overrides_annot src_annot models tenv proc_name then (
Option.iter sink_map ~f:(fun sink_map ->
let f_report =
report_annotation_stack analysis_data src_annot.Annot.class_name
report_annotation_stack analysis_data models src_annot.Annot.class_name
snk_annot.Annot.class_name
in
report_call_stack
Expand Down Expand Up @@ -226,8 +246,6 @@ let report_src_snk_paths proc_data annot_map src_annot_list snk_annot models =
List.iter ~f:(report_src_snk_path proc_data sink_map snk_annot models) src_annot_list


let annotation_of_str annot_str = {Annot.class_name= annot_str; parameters= []}

module AnnotationSpec = struct
type predicate = Tenv.t -> Procname.t -> bool

Expand Down

0 comments on commit 348ad42

Please sign in to comment.