diff --git a/infer/src/IR/Errlog.ml b/infer/src/IR/Errlog.ml index 852dcec17..27935849f 100644 --- a/infer/src/IR/Errlog.ml +++ b/infer/src/IR/Errlog.ml @@ -81,7 +81,9 @@ type err_data = ; visibility: Exceptions.visibility ; linters_def_file: string option ; doc_url: string option - ; access: string option } + ; access: string option + ; extras: Jsonbug_t.extra option + (* NOTE: Please consider adding new fields as part of extras *) } let compare_err_data err_data1 err_data2 = Location.compare err_data1.loc err_data2.loc @@ -232,7 +234,7 @@ let update errlog_old errlog_new = let log_issue procname ?clang_method_kind err_kind err_log loc (node_id, node_key) session ltr - ?linters_def_file ?doc_url ?access exn = + ?linters_def_file ?doc_url ?access ?extras exn = let lang = Typ.Procname.get_language procname in let error = Exceptions.recognize_exception exn in let err_kind = match error.kind with Some err_kind -> err_kind | _ -> err_kind in @@ -283,7 +285,8 @@ let log_issue procname ?clang_method_kind err_kind err_log loc (node_id, node_ke ; visibility= error.visibility ; linters_def_file ; doc_url - ; access } + ; access + ; extras } in let err_key = { err_kind diff --git a/infer/src/IR/Errlog.mli b/infer/src/IR/Errlog.mli index cf3c0fcb2..47339e5b6 100644 --- a/infer/src/IR/Errlog.mli +++ b/infer/src/IR/Errlog.mli @@ -55,7 +55,8 @@ type err_data = private ; visibility: Exceptions.visibility ; linters_def_file: string option ; doc_url: string option (** url to documentation of the issue type *) - ; access: string option } + ; access: string option + ; extras: Jsonbug_t.extra option } (** Type of the error log *) type t [@@deriving compare] @@ -95,4 +96,4 @@ val update : t -> t -> unit val log_issue : Typ.Procname.t -> ?clang_method_kind:string -> Exceptions.err_kind -> t -> Location.t -> int * Caml.Digest.t -> int -> loc_trace -> ?linters_def_file:string -> ?doc_url:string - -> ?access:string -> exn -> unit + -> ?access:string -> ?extras:Jsonbug_t.extra -> exn -> unit diff --git a/infer/src/atd/jsonbug.atd b/infer/src/atd/jsonbug.atd index a3278412c..ba2ba4287 100644 --- a/infer/src/atd/jsonbug.atd +++ b/infer/src/atd/jsonbug.atd @@ -13,6 +13,11 @@ type loc = { enum: int; } +type extra = { + ?cost_polynomial : string option; + ?cost_degree : int option +} + type jsonbug = { bug_class : string; kind : string; @@ -38,6 +43,7 @@ type jsonbug = { ?traceview_id: int option; censored_reason : string; ?access : string option; + ?extras : extra option; } type report = jsonbug list diff --git a/infer/src/backend/InferPrint.ml b/infer/src/backend/InferPrint.ml index 166299ea2..47210ffb1 100644 --- a/infer/src/backend/InferPrint.ml +++ b/infer/src/backend/InferPrint.ml @@ -282,7 +282,8 @@ module IssuesJson = struct ; doc_url= err_data.doc_url ; traceview_id= None ; censored_reason= censored_reason key.err_name source_file - ; access= err_data.access } + ; access= err_data.access + ; extras= err_data.extras } in if not !is_first_item then pp "," else is_first_item := false ; pp "%s@?" (Jsonbug_j.string_of_jsonbug bug) ) diff --git a/infer/src/backend/reporting.ml b/infer/src/backend/reporting.ml index b3787fc52..91f661249 100644 --- a/infer/src/backend/reporting.ml +++ b/infer/src/backend/reporting.ml @@ -10,12 +10,13 @@ module L = Logging type log_t = ?loc:Location.t -> ?node_id:int * Caml.Digest.t -> ?session:int -> ?ltr:Errlog.loc_trace - -> ?linters_def_file:string -> ?doc_url:string -> ?access:string -> exn -> unit + -> ?linters_def_file:string -> ?doc_url:string -> ?access:string -> ?extras:Jsonbug_t.extra + -> exn -> unit type log_issue_from_errlog = Errlog.t -> log_t let log_issue_from_errlog procname ?clang_method_kind err_kind err_log ?loc ?node_id ?session ?ltr - ?linters_def_file ?doc_url ?access exn = + ?linters_def_file ?doc_url ?access ?extras exn = let clang_method_kind = Option.map clang_method_kind ~f:ProcAttributes.string_of_clang_method_kind in @@ -34,11 +35,11 @@ let log_issue_from_errlog procname ?clang_method_kind err_kind err_log ?loc ?nod in let ltr = match ltr with None -> State.get_loc_trace () | Some ltr -> ltr in Errlog.log_issue procname ?clang_method_kind err_kind err_log loc node_id session ltr - ?linters_def_file ?doc_url ?access exn + ?linters_def_file ?doc_url ?access ?extras exn let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url - ?access exn = + ?access ?extras exn = let attrs = Summary.get_attributes summary in let procname = attrs.proc_name in let clang_method_kind = attrs.clang_method_kind in @@ -58,11 +59,11 @@ let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters else let err_log = Summary.get_err_log summary in log_issue_from_errlog procname ~clang_method_kind err_kind err_log ?loc ?node_id ?session ?ltr - ?linters_def_file ?doc_url ?access exn + ?linters_def_file ?doc_url ?access ?extras exn let log_issue_deprecated ?(store_summary= false) err_kind proc_name ?loc ?node_id ?session ?ltr - ?linters_def_file ?doc_url ?access exn = + ?linters_def_file ?doc_url ?access ?extras:_ exn = match Summary.get proc_name with | Some summary -> log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file @@ -94,10 +95,10 @@ let log_info_deprecated ?(store_summary= false) = let log_issue_external procname ?clang_method_kind err_kind ?loc ?node_id ?session ?ltr - ?linters_def_file ?doc_url ?access exn = + ?linters_def_file ?doc_url ?access ?extras exn = let errlog = IssueLog.get_errlog procname in log_issue_from_errlog procname ?clang_method_kind err_kind errlog ?loc ?node_id ?session ?ltr - ?linters_def_file ?doc_url ?access exn + ?linters_def_file ?doc_url ?access ?extras exn let is_suppressed ?(field_name= None) tenv proc_desc kind = diff --git a/infer/src/backend/reporting.mli b/infer/src/backend/reporting.mli index 7702f2c2a..dfb5be58f 100644 --- a/infer/src/backend/reporting.mli +++ b/infer/src/backend/reporting.mli @@ -11,7 +11,8 @@ open! IStd type log_t = ?loc:Location.t -> ?node_id:int * Caml.Digest.t -> ?session:int -> ?ltr:Errlog.loc_trace - -> ?linters_def_file:string -> ?doc_url:string -> ?access:string -> exn -> unit + -> ?linters_def_file:string -> ?doc_url:string -> ?access:string -> ?extras:Jsonbug_t.extra + -> exn -> unit type log_issue_from_errlog = Errlog.t -> log_t diff --git a/infer/src/biabduction/State.ml b/infer/src/biabduction/State.ml index 35129ed01..5520206ac 100644 --- a/infer/src/biabduction/State.ml +++ b/infer/src/biabduction/State.ml @@ -303,7 +303,7 @@ let mark_instr_fail exn = type log_issue = ?store_summary:bool -> Typ.Procname.t -> ?loc:Location.t -> ?node_id:int * Caml.Digest.t -> ?session:int -> ?ltr:Errlog.loc_trace -> ?linters_def_file:string -> ?doc_url:string - -> ?access:string -> exn -> unit + -> ?access:string -> ?extras:Jsonbug_t.extra -> exn -> unit let process_execution_failures (log_issue: log_issue) pname = let do_failure _ fs = diff --git a/infer/src/biabduction/State.mli b/infer/src/biabduction/State.mli index a8db61df4..6499120e6 100644 --- a/infer/src/biabduction/State.mli +++ b/infer/src/biabduction/State.mli @@ -77,7 +77,7 @@ val mk_find_duplicate_nodes : Procdesc.t -> Procdesc.Node.t -> Procdesc.NodeSet. type log_issue = ?store_summary:bool -> Typ.Procname.t -> ?loc:Location.t -> ?node_id:int * Caml.Digest.t -> ?session:int -> ?ltr:Errlog.loc_trace -> ?linters_def_file:string -> ?doc_url:string - -> ?access:string -> exn -> unit + -> ?access:string -> ?extras:Jsonbug_t.extra -> exn -> unit val process_execution_failures : log_issue -> Typ.Procname.t -> unit (** Process the failures during symbolic execution of a procedure *) diff --git a/infer/src/checkers/cost.ml b/infer/src/checkers/cost.ml index 40bf4613c..a65a1f740 100644 --- a/infer/src/checkers/cost.ml +++ b/infer/src/checkers/cost.ml @@ -858,6 +858,11 @@ type extras_TransferFunctionsWCET = ; get_node_nb_exec: Node.id -> BasicCost.astate ; summary: Summary.t } +let compute_errlog_extras cost = + { Jsonbug_t.cost_polynomial= Some (Format.asprintf "%a" BasicCost.pp cost) + ; cost_degree= BasicCost.degree cost } + + (* Calculate the final Worst Case Execution Time predicted for each node. It uses the basic cost of the nodes (computed previously by AnalyzerNodesBasicCost) and MinTrees which give an upperbound on the number of times a node can be executed @@ -902,7 +907,7 @@ module TransferFunctionsWCET = struct in Exceptions.Checkers (IssueType.expensive_execution_time_call, Localise.verbatim_desc message) in - Reporting.log_error summary ~loc ~ltr exn + Reporting.log_error summary ~loc ~ltr ~extras:(compute_errlog_extras cost) exn (* get a list of nodes and check if we have already reported for at @@ -980,7 +985,7 @@ let check_and_report_infinity cost proc_desc summary = let exn = Exceptions.Checkers (IssueType.infinite_execution_time_call, Localise.verbatim_desc message) in - Reporting.log_error ~loc summary exn + Reporting.log_error ~loc ~extras:(compute_errlog_extras cost) summary exn let checker ({Callbacks.tenv; proc_desc} as callback_args) : Summary.t = diff --git a/infer/src/unit/DifferentialTestsUtils.ml b/infer/src/unit/DifferentialTestsUtils.ml index d874ee8cc..4e171881f 100644 --- a/infer/src/unit/DifferentialTestsUtils.ml +++ b/infer/src/unit/DifferentialTestsUtils.ml @@ -37,7 +37,8 @@ let create_fake_jsonbug ?(bug_class= "bug_class") ?(kind= "kind") ?(bug_type= "b ; doc_url ; traceview_id= None ; censored_reason= "" - ; access= None } + ; access= None + ; extras= None } let pp_diff_of_list ~pp group_name fmt (expected, actual) =