[bug hash] Attempt for a better hash

Reviewed By: jeremydubreil

Differential Revision: D6162361

fbshipit-source-id: 895d7e4
master
Mehdi Bouaziz 7 years ago committed by Facebook Github Bot
parent 042dd7d9cb
commit 6047264e4a

@ -65,7 +65,7 @@ let compute_local_exception_line loc_trace =
snd (List_.fold_until ~init:(`Continue (None, None)) ~f:compute_local_exception_line loc_trace)
type node_id_key = {node_id: int; node_key: int}
type node_id_key = {node_id: int; node_key: Digest.t}
type err_key =
{ err_kind: Exceptions.err_kind

@ -36,7 +36,7 @@ val compute_local_exception_line : loc_trace -> int option
This extra information adds value to the report itself, and may avoid
digging into the trace to understand the cause of the report. *)
type node_id_key = private {node_id: int; node_key: int}
type node_id_key = private {node_id: int; node_key: Digest.t}
type err_key = private
{ err_kind: Exceptions.err_kind
@ -93,7 +93,7 @@ val update : t -> t -> unit
(** Update an old error log with a new one *)
val log_issue :
Exceptions.err_kind -> t -> Location.t -> int * int -> int -> loc_trace
Exceptions.err_kind -> t -> Location.t -> int * Digest.t -> int -> loc_trace
-> ?linters_def_file:string -> ?doc_url:string -> exn -> unit
(** {2 Functions for manipulating per-file error tables} *)

@ -686,7 +686,7 @@ let print_key = false
(** pretty print an error *)
let pp_err ~node_key loc ekind ex_name desc ml_loc_opt fmt () =
let kind = err_kind_string (if equal_err_kind ekind Kinfo then Kwarning else ekind) in
let pp_key fmt k = if print_key then F.fprintf fmt " key: %d " k else () in
let pp_key fmt k = if print_key then F.fprintf fmt " key: %s " (Digest.to_hex k) else () in
F.fprintf fmt "%a:%d: %s: %a %a%a%a@\n" SourceFile.pp loc.Location.file loc.Location.line kind
IssueType.pp ex_name Localise.pp_error_desc desc pp_key node_key L.pp_ml_loc_opt ml_loc_opt

@ -158,7 +158,7 @@ val print_exception_html : string -> exn -> unit
(** print a description of the exception to the html output *)
val pp_err :
node_key:int -> Location.t -> err_kind -> IssueType.t -> Localise.error_desc
node_key:Digest.t -> Location.t -> err_kind -> IssueType.t -> Localise.error_desc
-> Logging.ml_loc option -> Format.formatter -> unit -> unit
(** pretty print an error *)

@ -34,9 +34,9 @@ type jsonbug = {
procedure_start_line : int;
file : string;
bug_trace : json_trace_item list;
key : int;
key : string;
qualifier_tags : tag_value_record list;
hash : int;
hash : string;
?dotty : string option;
?infer_source_loc: loc option;
bug_type_hum: string;

@ -16,7 +16,7 @@ let of_reports ~(current_report: Jsonbug_t.report) ~(previous_report: Jsonbug_t.
let to_map report =
List.fold_left
~f:(fun map issue -> Map.add_multi map ~key:issue.Jsonbug_t.hash ~data:issue)
~init:Int.Map.empty report
~init:String.Map.empty report
in
let fold_aux ~key:_ ~data (left, both, right) =
match data with

@ -123,7 +123,7 @@ let skip_duplicated_types_on_filenames renamings (diff: Differential.t) : Differ
String.compare f1 f2
in
let cmp ((issue1, _) as issue_with_previous_file1) ((issue2, _) as issue_with_previous_file2) =
[%compare : int * string * issue_file_with_renaming]
[%compare : Digest.t * string * issue_file_with_renaming]
(issue1.Jsonbug_t.key, issue1.Jsonbug_t.bug_type, issue_with_previous_file1)
(issue2.Jsonbug_t.key, issue2.Jsonbug_t.bug_type, issue_with_previous_file2)
in
@ -180,7 +180,7 @@ let value_of_qualifier_tag qts tag =
type file_extension = string [@@deriving compare]
type weak_hash = string * string * string * int * string option [@@deriving compare]
type weak_hash = string * string * string * Digest.t * string option [@@deriving compare]
let skip_anonymous_class_renamings (diff: Differential.t) : Differential.t =
(*

@ -73,10 +73,10 @@ let error_desc_to_xml_tags error_desc =
let get_bug_hash (kind: string) (type_str: string) (procedure_id: string) (filename: string)
(node_key: int) (error_desc: Localise.error_desc) =
(node_key: Digest.t) (error_desc: Localise.error_desc) =
let qualifier_tag_call_procedure = Localise.error_desc_get_tag_call_procedure error_desc in
let qualifier_tag_value = Localise.error_desc_get_tag_value error_desc in
Hashtbl.hash
Utils.better_hash
( kind
, type_str
, procedure_id
@ -309,11 +309,12 @@ module IssuesCsv = struct
pp "\"%s\"," (Escape.escape_csv procedure_id) ;
pp "%s," filename ;
pp "\"%s\"," (Escape.escape_csv trace) ;
pp "\"%d\"," err_data.node_id_key.node_key ;
pp "\"%s\"," (Digest.to_hex err_data.node_id_key.node_key) ;
pp "\"%s\"," qualifier_tag_xml ;
pp "\"%d\","
(get_bug_hash kind type_str procedure_id filename err_data.node_id_key.node_key
key.err_desc) ;
pp "\"%s\","
( get_bug_hash kind type_str procedure_id filename err_data.node_id_key.node_key
key.err_desc
|> Digest.to_hex ) ;
pp "\"%d\"," !csv_issues_id ;
(* bug id *)
pp "\"%s\"," always_report ;
@ -399,10 +400,11 @@ module IssuesJson = struct
; procedure_start_line
; file
; bug_trace= loc_trace_to_jsonbug_record err_data.loc_trace key.err_kind
; key= err_data.node_id_key.node_key
; key= err_data.node_id_key.node_key |> Digest.to_hex
; qualifier_tags= Localise.Tags.tag_value_records_of_tags key.err_desc.tags
; hash=
get_bug_hash kind bug_type procedure_id file err_data.node_id_key.node_key key.err_desc
|> Digest.to_hex
; dotty= error_desc_to_dotty_string key.err_desc
; infer_source_loc= json_ml_loc
; bug_type_hum= key.err_name.IssueType.hum
@ -460,9 +462,9 @@ let pp_custom_of_report fmt report fields =
| `Issue_field_bug_trace ->
pp_trace fmt issue.bug_trace (comma_separator index)
| `Issue_field_key ->
Format.fprintf fmt "%s%d" (comma_separator index) issue.key
Format.fprintf fmt "%s%s" (comma_separator index) (Digest.to_hex issue.key)
| `Issue_field_hash ->
Format.fprintf fmt "%s%d" (comma_separator index) issue.hash
Format.fprintf fmt "%s%s" (comma_separator index) (Digest.to_hex issue.hash)
| `Issue_field_line_offset ->
Format.fprintf fmt "%s%d" (comma_separator index)
(issue.line - issue.procedure_start_line)
@ -479,7 +481,7 @@ let pp_custom_of_report fmt report fields =
let tests_jsonbug_compare bug1 bug2 =
let open Jsonbug_t in
[%compare : string * string * int * string * int]
[%compare : string * string * int * string * Digest.t]
(bug1.file, bug1.procedure, bug1.line - bug1.procedure_start_line, bug1.bug_type, bug1.hash)
(bug2.file, bug2.procedure, bug2.line - bug2.procedure_start_line, bug2.bug_type, bug2.hash)

@ -11,23 +11,27 @@ open! IStd
module L = Logging
type log_t =
?loc:Location.t -> ?node_id:int * int -> ?session:int -> ?ltr:Errlog.loc_trace
?loc:Location.t -> ?node_id:int * Digest.t -> ?session:int -> ?ltr:Errlog.loc_trace
-> ?linters_def_file:string -> ?doc_url:string -> exn -> unit
type log_issue_from_errlog = Errlog.t -> log_t
let log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url
exn =
let loc = match loc with None -> State.get_loc () | Some loc -> loc in
let node_id =
match node_id with None -> (State.get_node_id_key () :> int * int) | Some node_id -> node_id
in
let session =
match session with None -> (State.get_session () :> int) | Some session -> session
in
let ltr = match ltr with None -> State.get_loc_trace () | Some ltr -> ltr in
let issue_type = (Exceptions.recognize_exception exn).name in
if not Config.filtering (* no-filtering takes priority *) || issue_type.IssueType.enabled then
let loc = match loc with None -> State.get_loc () | Some loc -> loc in
let node_id =
match node_id with
| None ->
(State.get_node_id_key () :> int * Digest.t)
| Some node_id ->
node_id
in
let session =
match session with None -> (State.get_session () :> int) | Some session -> session
in
let ltr = match ltr with None -> State.get_loc_trace () | Some ltr -> ltr in
Errlog.log_issue err_kind err_log loc node_id session ltr ?linters_def_file ?doc_url exn

@ -12,7 +12,7 @@ open! IStd
(** Type of functions to report issues to the error_log in a spec. *)
type log_t =
?loc:Location.t -> ?node_id:int * int -> ?session:int -> ?ltr:Errlog.loc_trace
?loc:Location.t -> ?node_id:int * Digest.t -> ?session:int -> ?ltr:Errlog.loc_trace
-> ?linters_def_file:string -> ?doc_url:string -> exn -> unit
type log_issue_from_errlog = Errlog.t -> log_t

@ -27,7 +27,7 @@ type failure_stats =
; (* number of node failures (i.e. at least one instruction failure) *)
mutable node_ok: int
; (* number of node successes (i.e. no instruction failures) *)
mutable first_failure: (Location.t * (int * int) * int * Errlog.loc_trace * exn) option
mutable first_failure: (Location.t * (int * Digest.t) * int * Errlog.loc_trace * exn) option
(* exception at the first failure *) }
module NodeHash = Procdesc.NodeHash
@ -106,31 +106,31 @@ let get_node () = !gs.last_node
(** simple key for a node: just look at the instructions *)
let node_simple_key node =
let key = ref [] in
let add_key k = key := k :: !key in
let do_instr instr =
if Sil.instr_is_auxiliary instr then ()
let add_instr key instr =
if Sil.instr_is_auxiliary instr then key
else
match instr with
| Sil.Load _ ->
add_key 1
| Sil.Store _ ->
add_key 2
| Sil.Prune _ ->
add_key 3
| Sil.Call _ ->
add_key 4
| Sil.Nullify _ ->
add_key 5
| Sil.Abstract _ ->
add_key 6
| Sil.Remove_temps _ ->
add_key 7
| Sil.Declare_locals _ ->
add_key 8
let instr_key =
match instr with
| Sil.Load _ ->
1
| Sil.Store _ ->
2
| Sil.Prune _ ->
3
| Sil.Call _ ->
4
| Sil.Nullify _ ->
5
| Sil.Abstract _ ->
6
| Sil.Remove_temps _ ->
7
| Sil.Declare_locals _ ->
8
in
instr_key :: key
in
List.iter ~f:do_instr (Procdesc.Node.get_instrs node) ;
Hashtbl.hash !key
Procdesc.Node.get_instrs node |> List.fold ~init:[] ~f:add_instr |> Utils.better_hash
(** key for a node: look at the current node, successors and predecessors *)
@ -138,9 +138,11 @@ let node_key node =
let succs = Procdesc.Node.get_succs node in
let preds = Procdesc.Node.get_preds node in
let v =
(node_simple_key node, List.map ~f:node_simple_key succs, List.map ~f:node_simple_key preds)
( node_simple_key node
, List.rev_map ~f:node_simple_key succs
, List.rev_map ~f:node_simple_key preds )
in
Hashtbl.hash v
Utils.better_hash v
(** normalize the list of instructions by renaming let-bound ids *)
@ -320,7 +322,7 @@ let mark_instr_ok () =
let mark_instr_fail exn =
let loc = get_loc () in
let key = (get_node_id_key () :> int * int) in
let key = (get_node_id_key () :> int * Digest.t) in
let session = get_session () in
let loc_trace = get_loc_trace () in
let fs = get_failure_stats (get_node ()) in
@ -330,8 +332,9 @@ let mark_instr_fail exn =
type log_issue =
?store_summary:bool -> Typ.Procname.t -> ?loc:Location.t -> ?node_id:int * int -> ?session:int
-> ?ltr:Errlog.loc_trace -> ?linters_def_file:string -> ?doc_url:string -> exn -> unit
?store_summary:bool -> Typ.Procname.t -> ?loc:Location.t -> ?node_id:int * Digest.t
-> ?session:int -> ?ltr:Errlog.loc_trace -> ?linters_def_file:string -> ?doc_url:string -> exn
-> unit
let process_execution_failures (log_issue: log_issue) pname =
let do_failure _ fs =

@ -47,7 +47,7 @@ val get_node : unit -> Procdesc.Node.t
val get_node_id : unit -> Procdesc.Node.id
(** Get id of last node seen in symbolic execution *)
val get_node_id_key : unit -> Procdesc.Node.id * int
val get_node_id_key : unit -> Procdesc.Node.id * Digest.t
(** Get id and key of last node seen in symbolic execution *)
val get_normalized_pre :
@ -85,8 +85,9 @@ val mk_find_duplicate_nodes : Procdesc.t -> Procdesc.Node.t -> Procdesc.NodeSet.
and normalized (w.r.t. renaming of let - bound ids) list of instructions. *)
type log_issue =
?store_summary:bool -> Typ.Procname.t -> ?loc:Location.t -> ?node_id:int * int -> ?session:int
-> ?ltr:Errlog.loc_trace -> ?linters_def_file:string -> ?doc_url:string -> exn -> unit
?store_summary:bool -> Typ.Procname.t -> ?loc:Location.t -> ?node_id:int * Digest.t
-> ?session:int -> ?ltr:Errlog.loc_trace -> ?linters_def_file:string -> ?doc_url:string -> exn
-> unit
val process_execution_failures : log_issue -> Typ.Procname.t -> unit
(** Process the failures during symbolic execution of a procedure *)

@ -378,3 +378,5 @@ let without_gc ~f =
let yield () =
Unix.select ~read:[] ~write:[] ~except:[] ~timeout:(`After Time_ns.Span.min_value) |> ignore
let better_hash x = Marshal.to_string x [Marshal.No_sharing] |> Digest.string

@ -107,3 +107,6 @@ val without_gc : f:(unit -> unit) -> unit
val yield : unit -> unit
(** try to give the control back to the OS without sleeping too much *)
val better_hash : 'a -> Digest.t
(** Hashtbl.hash only hashes the first 10 meaningful values, [better_hash] uses everything. *)

@ -461,7 +461,7 @@ let log_frontend_issue translation_unit_context method_decl_opt (node: Ctl_parse
| Stmt st ->
CAst_utils.generate_key_stmt st
in
let key = Hashtbl.hash key_str in
let key = Utils.better_hash key_str in
Reporting.log_issue_from_errlog err_kind errlog exn ~loc:issue_desc.loc ~ltr:trace
~node_id:(0, key) ?linters_def_file ?doc_url:issue_desc.doc_url

@ -149,19 +149,19 @@ let test_relative_complements =
let test_skip_duplicated_types_on_filenames =
let current_report =
[ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2'.java" ~hash:22 ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1'.java" ~hash:11 ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1'.java" ~hash:111 ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_4.java" ~hash:4 ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2'.java" ~hash:222 ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_5.java" ~hash:55 () ]
[ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2'.java" ~hash:"22" ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1'.java" ~hash:"11" ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1'.java" ~hash:"111" ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_4.java" ~hash:"4" ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2'.java" ~hash:"222" ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_5.java" ~hash:"55" () ]
in
let previous_report =
[ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2'.java" ~hash:222 ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_5.java" ~hash:5 ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1.java" ~hash:1 ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_3.java" ~hash:3 ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2.java" ~hash:2 () ]
[ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2'.java" ~hash:"222" ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_5.java" ~hash:"5" ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1.java" ~hash:"1" ()
; create_fake_jsonbug ~bug_type:"bug_type_2" ~file:"file_3.java" ~hash:"3" ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_2.java" ~hash:"2" () ]
in
let renamings =
DifferentialFilters.FileRenamings.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY.from_renamings
@ -175,16 +175,16 @@ let test_skip_duplicated_types_on_filenames =
in
let do_assert _ =
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of introduced")
[4]
~pp_diff:(pp_diff_of_string_list "Hashes of introduced")
["4"]
(sorted_hashes_of_issues diff'.introduced) ;
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of fixed")
[3]
~pp_diff:(pp_diff_of_string_list "Hashes of fixed")
["3"]
(sorted_hashes_of_issues diff'.fixed) ;
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of preexisting")
[22; 55; 111; 222]
~pp_diff:(pp_diff_of_string_list "Hashes of preexisting")
["111"; "22"; "222"; "55"]
(sorted_hashes_of_issues diff'.preexisting)
in
"test_skip_duplicated_types_on_filenames" >:: do_assert
@ -219,15 +219,15 @@ let test_skip_anonymous_class_renamings =
input_diff
in
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of introduced")
~pp_diff:(pp_diff_of_string_list "Hashes of introduced")
exp_introduced
(sorted_hashes_of_issues diff'.introduced) ;
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of fixed")
~pp_diff:(pp_diff_of_string_list "Hashes of fixed")
exp_fixed
(sorted_hashes_of_issues diff'.fixed) ;
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of preexisting")
~pp_diff:(pp_diff_of_string_list "Hashes of preexisting")
exp_preexisting
(sorted_hashes_of_issues diff'.preexisting)
in
@ -240,112 +240,112 @@ let test_skip_anonymous_class_renamings =
( "com.whatever.package00.abcd."
^ "ABasicExampleFragment$83.onMenuItemActionExpand(android.view.MenuItem):b."
^ "5ab5e18cae498c35d887ce88f3d5fa82" )
~file:"a.java" ~key:1 ~qualifier_tags:qt1 ~hash:3 ()
~file:"a.java" ~key:"1" ~qualifier_tags:qt1 ~hash:"3" ()
; create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
( "com.whatever.package00.abcd."
^ "ABasicExampleFragment$83$7.onMenuItemActionExpand(android.view.MenuItem)."
^ "522cc747174466169781c9d2fc980dbc" )
~file:"a.java" ~key:1 ~qualifier_tags:qt1 ~hash:4 ()
~file:"a.java" ~key:"1" ~qualifier_tags:qt1 ~hash:"4" ()
; create_fake_jsonbug ~bug_type:"bug_type_2"
~procedure_id:"procid5.c854fd4a98113d9ab5b82deb3545de89" ~file:"b.java" ~key:5
~hash:5 () ]
~procedure_id:"procid5.c854fd4a98113d9ab5b82deb3545de89" ~file:"b.java" ~key:"5"
~hash:"5" () ]
~previous_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
( "com.whatever.package00.abcd."
^ "ABasicExampleFragment$9.onMenuItemActionExpand(android.view.MenuItem):bo."
^ "ba1776155fba2899542401da5bc779a5" )
~file:"a.java" ~key:1 ~qualifier_tags:qt1 ~hash:1 ()
~file:"a.java" ~key:"1" ~qualifier_tags:qt1 ~hash:"1" ()
; create_fake_jsonbug ~bug_type:"bug_type_2"
~procedure_id:"procid2.92095aee3f1884c37e96feae031f4931" ~file:"b.java" ~key:2
~hash:2 () ]
, ([4; 5], [2], [3]) )
~procedure_id:"procid2.92095aee3f1884c37e96feae031f4931" ~file:"b.java" ~key:"2"
~hash:"2" () ]
, (["4"; "5"], ["2"], ["3"]) )
; ( "test_skip_anonymous_class_renamings_with_empty_qualifier_tags"
, Differential.of_reports
~current_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class$1.foo():bool.bf13089cf4c47ff8ff089a1a4767324f"
~file:"a.java" ~key:1 ~hash:1 ()
~file:"a.java" ~key:"1" ~hash:"1" ()
; create_fake_jsonbug ~bug_type:"bug_type_2"
~procedure_id:
"com.whatever.package.Class$1.foo():bool.bf13089cf4c47ff8ff089a1a4767324f"
~file:"a.java" ~key:1 ~hash:3 () ]
~file:"a.java" ~key:"1" ~hash:"3" () ]
~previous_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class$21$1.foo():bool.db89561ad9dab28587c8c04833f09b03"
~file:"a.java" ~key:1 ~hash:2 ()
~file:"a.java" ~key:"1" ~hash:"2" ()
; create_fake_jsonbug ~bug_type:"bug_type_2"
~procedure_id:
"com.whatever.package.Class$8.foo():bool.cffd4e941668063eb802183dbd3e856d"
~file:"a.java" ~key:1 ~hash:4 () ]
, ([1], [2], [3]) )
~file:"a.java" ~key:"1" ~hash:"4" () ]
, (["1"], ["2"], ["3"]) )
; ( "test_skip_anonymous_class_renamings_with_matching_non_anonymous_procedure_ids"
, Differential.of_reports
~current_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class.foo():bool.919f37fd0993058a01f438210ba8a247"
~file:"a.java" ~key:1 ~hash:1 ()
~file:"a.java" ~key:"1" ~hash:"1" ()
; create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class.foo():bool.919f37fd0993058a01f438210ba8a247"
~file:"a.java" ~key:1 ~hash:3 () ]
~file:"a.java" ~key:"1" ~hash:"3" () ]
~previous_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class.foo():bool.919f37fd0993058a01f438210ba8a247"
~file:"a.java" ~key:1 ~hash:2 ()
~file:"a.java" ~key:"1" ~hash:"2" ()
; create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class.foo():bool.919f37fd0993058a01f438210ba8a247"
~file:"a.java" ~key:1 ~hash:4 () ]
, ([1; 3], [2; 4], []) )
~file:"a.java" ~key:"1" ~hash:"4" () ]
, (["1"; "3"], ["2"; "4"], []) )
; ( "test_skip_anonymous_class_renamings_with_non_java_files"
, Differential.of_reports
~current_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class$3$1.foo():bool.9ff39eb5c53c81da9f6a7ade324345b6"
~file:"a.java" ~key:1 ~hash:1 ()
~file:"a.java" ~key:"1" ~hash:"1" ()
; create_fake_jsonbug ~bug_type:"bug_type_2"
~procedure_id:
"com.whatever.package.Class$1.foo():bool.bf13089cf4c47ff8ff089a1a4767324f"
~file:"a.mm" ~key:1 ~hash:3 () ]
~file:"a.mm" ~key:"1" ~hash:"3" () ]
~previous_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class$21$1.foo():bool.db89561ad9dab28587c8c04833f09b03"
~file:"a.java" ~key:1 ~hash:2 ()
~file:"a.java" ~key:"1" ~hash:"2" ()
; create_fake_jsonbug ~bug_type:"bug_type_2"
~procedure_id:
"com.whatever.package.Class$8.foo():bool.cffd4e941668063eb802183dbd3e856d"
~file:"a.mm" ~key:1 ~hash:4 () ]
, ([3], [4], [1]) )
~file:"a.mm" ~key:"1" ~hash:"4" () ]
, (["3"], ["4"], ["1"]) )
; ( "test_skip_anonymous_class_renamings_with_different_call_procedure_qualifier_tags"
, Differential.of_reports
~current_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class$3$1.foo():bool.9ff39eb5c53c81da9f6a7ade324345b6"
~file:"a.java" ~key:1 ~qualifier_tags:qt1 ~hash:1 () ]
~file:"a.java" ~key:"1" ~qualifier_tags:qt1 ~hash:"1" () ]
~previous_report:
[ create_fake_jsonbug ~bug_type:"bug_type_1"
~procedure_id:
"com.whatever.package.Class$21$1.foo():bool.db89561ad9dab28587c8c04833f09b03"
~file:"a.java" ~key:1 ~qualifier_tags:qt2 ~hash:2 () ]
, ([1], [2], []) ) ]
~file:"a.java" ~key:"1" ~qualifier_tags:qt2 ~hash:"2" () ]
, (["1"], ["2"], []) ) ]
|> List.map ~f:(fun (name, diff, expected_output) -> name >:: create_test diff expected_output)
let test_interesting_paths_filter =
let report =
[ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1.java" ~hash:1 ()
[ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1.java" ~hash:"1" ()
; create_fake_jsonbug ~bug_type:IssueType.null_dereference.unique_id ~file:"file_2.java"
~hash:2 ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_4.java" ~hash:4 () ]
~hash:"2" ()
; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_4.java" ~hash:"4" () ]
in
let create_test interesting_paths expected_hashes _ =
let filter =
@ -353,15 +353,17 @@ let test_interesting_paths_filter =
interesting_paths
in
let filtered_report = filter report in
assert_equal ~pp_diff:(pp_diff_of_int_list "Bug hash") expected_hashes
assert_equal
~pp_diff:(pp_diff_of_string_list "Bug hash")
expected_hashes
(sorted_hashes_of_issues filtered_report)
in
[ ("test_interesting_paths_filter_with_none_interesting_paths", None, [1; 2; 4])
[ ("test_interesting_paths_filter_with_none_interesting_paths", None, ["1"; "2"; "4"])
; ( "test_interesting_paths_filter_with_some_interesting_paths"
, Some
[ SourceFile.create ~warn_on_error:false "file_not_existing.java"
; SourceFile.create ~warn_on_error:false "file_4.java" ]
, [4] )
, ["4"] )
; ( "test_interesting_paths_filter_with_some_interesting_paths_that_are_not_in_report"
, Some
[ SourceFile.create ~warn_on_error:false "file_not_existing.java"

@ -12,15 +12,17 @@ open OUnit2
open DifferentialTestsUtils
let current_report =
[ create_fake_jsonbug ~hash:3 ()
; create_fake_jsonbug ~hash:1 ()
; create_fake_jsonbug ~hash:2 ()
; create_fake_jsonbug ~hash:2 ()
; create_fake_jsonbug ~hash:2 () ]
[ create_fake_jsonbug ~hash:"3" ()
; create_fake_jsonbug ~hash:"1" ()
; create_fake_jsonbug ~hash:"2" ()
; create_fake_jsonbug ~hash:"2" ()
; create_fake_jsonbug ~hash:"2" () ]
let previous_report =
[create_fake_jsonbug ~hash:1 (); create_fake_jsonbug ~hash:4 (); create_fake_jsonbug ~hash:1 ()]
[ create_fake_jsonbug ~hash:"1" ()
; create_fake_jsonbug ~hash:"4" ()
; create_fake_jsonbug ~hash:"1" () ]
let diff = Differential.of_reports ~current_report ~previous_report
@ -30,7 +32,7 @@ let test_diff_keeps_duplicated_hashes =
let hashes_expected = 3 in
let hashes_found =
List.fold ~init:0
~f:(fun acc i -> if Int.equal i.Jsonbug_t.hash 2 then acc + 1 else acc)
~f:(fun acc i -> if String.equal i.Jsonbug_t.hash "2" then acc + 1 else acc)
diff.introduced
in
let pp_diff fmt (expected, actual) =
@ -45,16 +47,16 @@ let test_diff_keeps_duplicated_hashes =
let test_set_operations =
let do_assert _ =
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of introduced")
[2; 2; 2; 3]
~pp_diff:(pp_diff_of_string_list "Hashes of introduced")
["2"; "2"; "2"; "3"]
(sorted_hashes_of_issues diff.introduced) ;
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of fixed")
[4]
~pp_diff:(pp_diff_of_string_list "Hashes of fixed")
["4"]
(sorted_hashes_of_issues diff.fixed) ;
assert_equal
~pp_diff:(pp_diff_of_int_list "Hashes of preexisting")
[1]
~pp_diff:(pp_diff_of_string_list "Hashes of preexisting")
["1"]
(sorted_hashes_of_issues diff.preexisting)
in
"test_set_operations" >:: do_assert

@ -12,8 +12,8 @@ open! IStd
let create_fake_jsonbug ?(bug_class= "bug_class") ?(kind= "kind") ?(bug_type= "bug_type")
?(qualifier= "qualifier") ?(severity= "severity") ?(visibility= "visibility") ?(line= 1)
?(column= 1) ?(procedure= "procedure") ?(procedure_id= "procedure_id")
?(procedure_start_line= 1) ?(file= "file/at/a/certain/path.java") ?(bug_trace= []) ?(key= 1234)
?(qualifier_tags= []) ?(hash= 1) ?(dotty= None) ?(infer_source_loc= None)
?(procedure_start_line= 1) ?(file= "file/at/a/certain/path.java") ?(bug_trace= [])
?(key= "1234") ?(qualifier_tags= []) ?(hash= "1") ?(dotty= None) ?(infer_source_loc= None)
?(linters_def_file= Some "file/at/certain/path.al") ?doc_url () : Jsonbug_t.jsonbug =
{ bug_class
; kind
@ -39,16 +39,17 @@ let create_fake_jsonbug ?(bug_class= "bug_class") ?(kind= "kind") ?(bug_type= "b
; traceview_id= None }
let pp_diff_of_int_list group_name fmt (expected, actual) =
Format.fprintf fmt "[%s]: Expected: [%a] Found: [%a]" group_name
(Pp.comma_seq Format.pp_print_int)
expected
(Pp.comma_seq Format.pp_print_int)
actual
let pp_diff_of_list ~pp group_name fmt (expected, actual) =
Format.fprintf fmt "[%s]: Expected: [%a] Found: [%a]" group_name (Pp.comma_seq pp) expected
(Pp.comma_seq pp) actual
let pp_diff_of_string_list = pp_diff_of_list ~pp:Format.pp_print_string
let pp_diff_of_int_list = pp_diff_of_list ~pp:Format.pp_print_int
(* Sort hashes to make things easier to compare *)
let sorted_hashes_of_issues issues =
let hash i = i.Jsonbug_t.hash in
List.sort ~cmp:Int.compare (List.map ~f:hash issues)
List.sort ~cmp:String.compare (List.rev_map ~f:hash issues)

@ -158,8 +158,8 @@ codetoanalyze/java/infer/ResourceLeaks.java, int ResourceLeaks.fileOutputStreamT
codetoanalyze/java/infer/ResourceLeaks.java, int ResourceLeaks.readConfigNotCloseStream(String), 5, RESOURCE_LEAK, [start of procedure readConfigNotCloseStream(...)]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.activityObtainTypedArrayAndLeak(Activity), 2, RESOURCE_LEAK, [start of procedure activityObtainTypedArrayAndLeak(...),start of procedure ignore(...),return from a call to void ResourceLeaks.ignore(TypedArray)]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.contextObtainTypedArrayAndLeak(Context), 2, RESOURCE_LEAK, [start of procedure contextObtainTypedArrayAndLeak(...),start of procedure ignore(...),return from a call to void ResourceLeaks.ignore(TypedArray)]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.copyFileLeak(File,File), 11, RESOURCE_LEAK, [start of procedure copyFileLeak(...),Skipping transferTo(...): unknown method,Taking true branch,exception java.io.IOException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.copyFileLeak(File,File), 11, RESOURCE_LEAK, [start of procedure copyFileLeak(...),exception java.io.FileNotFoundException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.copyFileLeak(File,File), 11, RESOURCE_LEAK, [start of procedure copyFileLeak(...),Skipping transferTo(...): unknown method,Taking true branch,exception java.io.IOException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.deflaterLeak(), 1, RESOURCE_LEAK, [start of procedure deflaterLeak()]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.fileInputStreamNotClosedAfterRead(), 6, RESOURCE_LEAK, [start of procedure fileInputStreamNotClosedAfterRead(),exception java.io.IOException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.fileOutputStreamNotClosed(), 1, RESOURCE_LEAK, [start of procedure fileOutputStreamNotClosed()]

@ -168,8 +168,8 @@ codetoanalyze/java/infer/ResourceLeaks.java, int ResourceLeaks.readConfigNotClos
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.NoResourceLeakWarningAfterCheckState(File,int), 2, PRECONDITION_NOT_MET, [start of procedure NoResourceLeakWarningAfterCheckState(...),Taking false branch]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.activityObtainTypedArrayAndLeak(Activity), 2, RESOURCE_LEAK, [start of procedure activityObtainTypedArrayAndLeak(...),start of procedure ignore(...),return from a call to void ResourceLeaks.ignore(TypedArray)]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.contextObtainTypedArrayAndLeak(Context), 2, RESOURCE_LEAK, [start of procedure contextObtainTypedArrayAndLeak(...),start of procedure ignore(...),return from a call to void ResourceLeaks.ignore(TypedArray)]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.copyFileLeak(File,File), 11, RESOURCE_LEAK, [start of procedure copyFileLeak(...),Skipping transferTo(...): unknown method,Taking true branch,exception java.io.IOException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.copyFileLeak(File,File), 11, RESOURCE_LEAK, [start of procedure copyFileLeak(...),exception java.io.FileNotFoundException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.copyFileLeak(File,File), 11, RESOURCE_LEAK, [start of procedure copyFileLeak(...),Skipping transferTo(...): unknown method,Taking true branch,exception java.io.IOException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.deflaterLeak(), 1, RESOURCE_LEAK, [start of procedure deflaterLeak()]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.fileInputStreamNotClosedAfterRead(), 6, RESOURCE_LEAK, [start of procedure fileInputStreamNotClosedAfterRead(),exception java.io.IOException]
codetoanalyze/java/infer/ResourceLeaks.java, void ResourceLeaks.fileOutputStreamNotClosed(), 1, RESOURCE_LEAK, [start of procedure fileOutputStreamNotClosed()]

@ -23,8 +23,8 @@ codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorde
codetoanalyze/objc/errors/warnings/ParameterNotNullableExample.m, FBAudioRecorder_test, 3, NULL_DEREFERENCE, [start of procedure test,Message recordState with receiver nil returns nil.]
codetoanalyze/objc/shared/assertions/NSAssert_example.m, NSAssert_addTarget:, 1, MEMORY_LEAK, [start of procedure addTarget:,Condition is false,Condition is true,Condition is true]
codetoanalyze/objc/shared/assertions/NSAssert_example.m, NSAssert_initWithRequest:, 1, MEMORY_LEAK, [start of procedure initWithRequest:,Condition is false,Condition is true,Condition is true]
codetoanalyze/objc/shared/assertions/NSAssert_example.m, test1, 1, MEMORY_LEAK, [start of procedure test1(),Condition is false,Condition is true,Condition is true,Condition is true]
codetoanalyze/objc/shared/assertions/NSAssert_example.m, test1, 1, MEMORY_LEAK, [start of procedure test1(),Condition is false,Condition is true,Condition is true]
codetoanalyze/objc/shared/assertions/NSAssert_example.m, test1, 1, MEMORY_LEAK, [start of procedure test1(),Condition is false,Condition is true,Condition is true,Condition is true]
codetoanalyze/objc/shared/assertions/NSAssert_example.m, test2, 1, MEMORY_LEAK, [start of procedure test2(),Condition is false,Condition is true,Condition is true]
codetoanalyze/objc/shared/block/BlockVar.m, BlockVar_blockPostBad, 5, NULL_DEREFERENCE, [start of procedure blockPostBad,start of procedure block,return from a call to objc_blockBlockVar_blockPostBad_2]
codetoanalyze/objc/shared/block/BlockVar.m, BlockVar_capturedNullDeref, 5, NULL_DEREFERENCE, [start of procedure capturedNullDeref,start of procedure block]

Loading…
Cancel
Save