move visibility into IssueType and make it static, move severity but keep it dynamic

Summary:
- "visibility" (whether an issue to report is something to show the user
  or something that is only used for debugging or for detecting other
  issues) is an intrinsic property of an issue type and thus belongs in
  `IssueType.t`.

- "severity" (warning/error/...) is something that each issue should
  have a default for ("a memory leak is by default an ERROR", a
  "condition always true is by default a warning"), but can also be
  overriden at run-time. Right now only nullsafe uses that capability:
  when in "strict mode", some warnings become errors. We can imagine
  extending this to other issue types, or even providing config flags to
  turn warnings into errors, like compilers often have.

To guess the default severity (since it's dynamic it can be hard to know
for sure!), I tried to find places where it was reported as the source
of truth, but also later diffs test these defaults against our tests (by
removing most of the dynamic changes in severity).

With this diff there are 3 places where severity is set:
1. The default severity in IssueType.t: this is unused for now.
2. The severity from `Exceptions.recognize_exception`: this is
   semi-statically determined and, if set, takes precedence over number 3 (which looks wrong to me!)
3. The severity passed to `Errlog.log_issue` when we actually add an
   issue to the error log: this is used only when (2) is unset.

The next diffs will make 1 the default, delete 2, and make 3 optional
but override 1 when passed.

Reviewed By: skcho

Differential Revision: D21904538

fbshipit-source-id: a674b42d8
master
Jules Villard 5 years ago committed by Facebook GitHub Bot
parent 341e719fd4
commit c9fc41f97c

@ -72,8 +72,7 @@ type node =
| FrontendNode of {node_key: Procdesc.NodeKey.t} | FrontendNode of {node_key: Procdesc.NodeKey.t}
| BackendNode of {node: Procdesc.Node.t} | BackendNode of {node: Procdesc.Node.t}
type err_key = type err_key = {severity: IssueType.severity; issue_type: IssueType.t; err_desc: Localise.error_desc}
{severity: Exceptions.severity; issue_type: IssueType.t; err_desc: Localise.error_desc}
[@@deriving compare] [@@deriving compare]
(** Data associated to a specific error *) (** Data associated to a specific error *)
@ -84,7 +83,7 @@ type err_data =
; loc: Location.t ; loc: Location.t
; loc_in_ml_source: L.ocaml_pos option ; loc_in_ml_source: L.ocaml_pos option
; loc_trace: loc_trace ; loc_trace: loc_trace
; visibility: Exceptions.visibility ; visibility: IssueType.visibility
; linters_def_file: string option ; linters_def_file: string option
; doc_url: string option ; doc_url: string option
; access: string option ; access: string option
@ -109,7 +108,7 @@ module ErrLogHash = struct
let hash key = Hashtbl.hash (key.severity, key.issue_type, Localise.error_desc_hash key.err_desc) let hash key = Hashtbl.hash (key.severity, key.issue_type, Localise.error_desc_hash key.err_desc)
let equal key1 key2 = let equal key1 key2 =
[%compare.equal: Exceptions.severity * IssueType.t] (key1.severity, key1.issue_type) [%compare.equal: IssueType.severity * IssueType.t] (key1.severity, key1.issue_type)
(key2.severity, key2.issue_type) (key2.severity, key2.issue_type)
&& Localise.error_desc_equal key1.err_desc key2.err_desc && Localise.error_desc_equal key1.err_desc key2.err_desc
end end
@ -143,7 +142,7 @@ let fold (f : err_key -> err_data -> 'a -> 'a) t acc =
(** Print errors from error log *) (** Print errors from error log *)
let pp_errors fmt (errlog : t) = let pp_errors fmt (errlog : t) =
let f key _ = let f key _ =
if Exceptions.equal_severity key.severity Exceptions.Error then if IssueType.equal_severity key.severity Error then
F.fprintf fmt "%a@ " IssueType.pp key.issue_type F.fprintf fmt "%a@ " IssueType.pp key.issue_type
in in
ErrLogHash.iter f errlog ErrLogHash.iter f errlog
@ -152,7 +151,7 @@ let pp_errors fmt (errlog : t) =
(** Print warnings from error log *) (** Print warnings from error log *)
let pp_warnings fmt (errlog : t) = let pp_warnings fmt (errlog : t) =
let f key _ = let f key _ =
if Exceptions.equal_severity key.severity Exceptions.Warning then if IssueType.equal_severity key.severity Warning then
F.fprintf fmt "%a %a@ " IssueType.pp key.issue_type Localise.pp_error_desc key.err_desc F.fprintf fmt "%a %a@ " IssueType.pp key.issue_type Localise.pp_error_desc key.err_desc
in in
ErrLogHash.iter f errlog ErrLogHash.iter f errlog
@ -168,16 +167,16 @@ let pp_html source path_to_root fmt (errlog : t) =
ErrDataSet.iter (pp_nodeid_session_loc fmt) err_datas ErrDataSet.iter (pp_nodeid_session_loc fmt) err_datas
in in
let pp_err_log ek key err_datas = let pp_err_log ek key err_datas =
if Exceptions.equal_severity key.severity ek then if IssueType.equal_severity key.severity ek then
F.fprintf fmt "<br>%a %a %a" IssueType.pp key.issue_type Localise.pp_error_desc key.err_desc F.fprintf fmt "<br>%a %a %a" IssueType.pp key.issue_type Localise.pp_error_desc key.err_desc
pp_eds err_datas pp_eds err_datas
in in
let pp severity = let pp severity =
F.fprintf fmt "%a%s DURING FOOTPRINT@\n" Io_infer.Html.pp_hline () F.fprintf fmt "%a%s DURING FOOTPRINT@\n" Io_infer.Html.pp_hline ()
(Exceptions.severity_string severity) ; (IssueType.string_of_severity severity) ;
ErrLogHash.iter (pp_err_log severity) errlog ErrLogHash.iter (pp_err_log severity) errlog
in in
List.iter Exceptions.[Advice; Error; Info; Like; Warning] ~f:pp List.iter IssueType.all_of_severity ~f:pp
(** Add an error description to the error log unless there is one already at the same node + (** Add an error description to the error log unless there is one already at the same node +
@ -223,9 +222,8 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
false false
in in
let should_report = let should_report =
Exceptions.equal_visibility error.visibility Exceptions.Exn_user IssueType.equal_visibility error.issue_type.visibility User
|| Config.developer_mode || (Config.developer_mode && IssueType.equal_visibility error.issue_type.visibility Developer)
&& Exceptions.equal_visibility error.visibility Exceptions.Exn_developer
in in
if should_report && (not hide_java_loc_zero) && not hide_memory_error then if should_report && (not hide_java_loc_zero) && not hide_memory_error then
let added = let added =
@ -245,7 +243,7 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
; loc ; loc
; loc_in_ml_source= error.ocaml_pos ; loc_in_ml_source= error.ocaml_pos
; loc_trace= ltr ; loc_trace= ltr
; visibility= error.visibility ; visibility= error.issue_type.visibility
; linters_def_file ; linters_def_file
; doc_url ; doc_url
; access ; access
@ -260,7 +258,7 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
"@\n%a@\n@?" "@\n%a@\n@?"
(Exceptions.pp_err loc severity error.issue_type error.description error.ocaml_pos) (Exceptions.pp_err loc severity error.issue_type error.description error.ocaml_pos)
() ; () ;
if not (Exceptions.equal_severity severity Exceptions.Error) then ( if not (IssueType.equal_severity severity Error) then (
let warn_str = let warn_str =
let pp fmt = let pp fmt =
Format.fprintf fmt "%s %a" error.issue_type.unique_id Localise.pp_error_desc Format.fprintf fmt "%s %a" error.issue_type.unique_id Localise.pp_error_desc
@ -269,12 +267,12 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
F.asprintf "%t" pp F.asprintf "%t" pp
in in
let d = let d =
match severity with match (severity : IssueType.severity) with
| Exceptions.Error -> | Error ->
L.d_error L.d_error
| Exceptions.Warning -> | Warning ->
L.d_warning L.d_warning
| Exceptions.Info | Exceptions.Advice | Exceptions.Like -> | Info | Advice | Like ->
L.d_info L.d_info
in in
d warn_str ; d warn_str ;

@ -41,7 +41,7 @@ type node =
| BackendNode of {node: Procdesc.Node.t} | BackendNode of {node: Procdesc.Node.t}
type err_key = private type err_key = private
{severity: Exceptions.severity; issue_type: IssueType.t; err_desc: Localise.error_desc} {severity: IssueType.severity; issue_type: IssueType.t; err_desc: Localise.error_desc}
[@@deriving compare] [@@deriving compare]
(** Data associated to a specific error *) (** Data associated to a specific error *)
@ -52,7 +52,7 @@ type err_data = private
; loc: Location.t ; loc: Location.t
; loc_in_ml_source: Logging.ocaml_pos option ; loc_in_ml_source: Logging.ocaml_pos option
; loc_trace: loc_trace ; loc_trace: loc_trace
; visibility: Exceptions.visibility ; visibility: IssueType.visibility
; linters_def_file: string option ; linters_def_file: string option
; doc_url: string option (** url to documentation of the issue type *) ; doc_url: string option (** url to documentation of the issue type *)
; access: string option ; access: string option
@ -88,7 +88,7 @@ val update : t -> t -> unit
(** Update an old error log with a new one *) (** Update an old error log with a new one *)
val log_issue : val log_issue :
Exceptions.severity IssueType.severity
-> t -> t
-> loc:Location.t -> loc:Location.t
-> node:node -> node:node

@ -10,20 +10,6 @@ open! IStd
module L = Logging module L = Logging
module F = Format module F = Format
(** visibility of the exception *)
type visibility =
| Exn_user (** always add to error log *)
| Exn_developer (** only add to error log in developer mode *)
| Exn_system (** never add to error log *)
[@@deriving compare]
let equal_visibility = [%compare.equal: visibility]
(** severity of the report *)
type severity = Like | Info | Advice | Warning | Error [@@deriving compare]
let equal_severity = [%compare.equal: severity]
exception Abduction_case_not_implemented of L.ocaml_pos exception Abduction_case_not_implemented of L.ocaml_pos
exception Analysis_stops of Localise.error_desc * L.ocaml_pos option exception Analysis_stops of Localise.error_desc * L.ocaml_pos option
@ -48,7 +34,7 @@ exception Class_cast_exception of Localise.error_desc * L.ocaml_pos
exception Condition_always_true_false of Localise.error_desc * bool * L.ocaml_pos exception Condition_always_true_false of Localise.error_desc * bool * L.ocaml_pos
exception Custom_error of string * Localise.error_desc exception Custom_error of string * IssueType.severity * Localise.error_desc
exception exception
Dangling_pointer_dereference of bool (* is it user visible? *) * Localise.error_desc * L.ocaml_pos Dangling_pointer_dereference of bool (* is it user visible? *) * Localise.error_desc * L.ocaml_pos
@ -115,8 +101,7 @@ type t =
{ issue_type: IssueType.t { issue_type: IssueType.t
; description: Localise.error_desc ; description: Localise.error_desc
; ocaml_pos: L.ocaml_pos option (** location in the infer source code *) ; ocaml_pos: L.ocaml_pos option (** location in the infer source code *)
; visibility: visibility ; severity: IssueType.severity option }
; severity: severity option }
let recognize_exception exn = let recognize_exception exn =
match exn with match exn with
@ -124,182 +109,145 @@ let recognize_exception exn =
{ issue_type= IssueType.abduction_case_not_implemented { issue_type= IssueType.abduction_case_not_implemented
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Analysis_stops (desc, ocaml_pos_opt) -> | Analysis_stops (desc, ocaml_pos_opt) ->
{ issue_type= IssueType.biabduction_analysis_stops { issue_type= IssueType.biabduction_analysis_stops
; description= desc ; description= desc
; ocaml_pos= ocaml_pos_opt ; ocaml_pos= ocaml_pos_opt
; visibility= Exn_developer
; severity= None } ; severity= None }
| Array_of_pointsto ocaml_pos -> | Array_of_pointsto ocaml_pos ->
{ issue_type= IssueType.array_of_pointsto { issue_type= IssueType.array_of_pointsto
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Array_out_of_bounds_l1 (desc, ocaml_pos) -> | Array_out_of_bounds_l1 (desc, ocaml_pos) ->
{ issue_type= IssueType.array_out_of_bounds_l1 { issue_type= IssueType.array_out_of_bounds_l1
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= Some Error } ; severity= Some Error }
| Array_out_of_bounds_l2 (desc, ocaml_pos) -> | Array_out_of_bounds_l2 (desc, ocaml_pos) ->
{ issue_type= IssueType.array_out_of_bounds_l2 { issue_type= IssueType.array_out_of_bounds_l2
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Array_out_of_bounds_l3 (desc, ocaml_pos) -> | Array_out_of_bounds_l3 (desc, ocaml_pos) ->
{ issue_type= IssueType.array_out_of_bounds_l3 { issue_type= IssueType.array_out_of_bounds_l3
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Assert_failure (f, l, c) -> | Assert_failure (f, l, c) ->
let ocaml_pos = (f, l, c, c) in let ocaml_pos = (f, l, c, c) in
{ issue_type= IssueType.assert_failure { issue_type= IssueType.assert_failure
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Bad_footprint ocaml_pos -> | Bad_footprint ocaml_pos ->
{ issue_type= IssueType.bad_footprint { issue_type= IssueType.bad_footprint
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Biabd_use_after_free (desc, ocaml_pos) -> | Biabd_use_after_free (desc, ocaml_pos) ->
{ issue_type= IssueType.biabd_use_after_free { issue_type= IssueType.biabd_use_after_free
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Cannot_star ocaml_pos -> | Cannot_star ocaml_pos ->
{ issue_type= IssueType.cannot_star { issue_type= IssueType.cannot_star
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Class_cast_exception (desc, ocaml_pos) -> | Class_cast_exception (desc, ocaml_pos) ->
{ issue_type= IssueType.class_cast_exception { issue_type= IssueType.class_cast_exception
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Condition_always_true_false (desc, b, ocaml_pos) -> | Condition_always_true_false (desc, b, ocaml_pos) ->
let issue_type = let issue_type =
if b then IssueType.biabd_condition_always_true else IssueType.biabd_condition_always_false if b then IssueType.biabd_condition_always_true else IssueType.biabd_condition_always_false
in in
{ issue_type {issue_type; description= desc; ocaml_pos= Some ocaml_pos; severity= None}
; description= desc | Custom_error (error_msg, severity, desc) ->
; ocaml_pos= Some ocaml_pos { issue_type= IssueType.register_from_string ~id:error_msg severity Biabduction
; visibility= Exn_user
; severity= None }
| Custom_error (error_msg, desc) ->
{ issue_type= IssueType.register_from_string ~id:error_msg Biabduction
; description= desc ; description= desc
; ocaml_pos= None ; ocaml_pos= None
; visibility= Exn_user
; severity= None } ; severity= None }
| Dangling_pointer_dereference (user_visible, desc, ocaml_pos) -> | Dangling_pointer_dereference (user_visible, desc, ocaml_pos) ->
let issue_type, visibility = let issue_type =
if user_visible then (IssueType.dangling_pointer_dereference, Exn_user) if user_visible then IssueType.dangling_pointer_dereference
else (IssueType.dangling_pointer_dereference_maybe, Exn_developer) else IssueType.dangling_pointer_dereference_maybe
in in
{issue_type; description= desc; ocaml_pos= Some ocaml_pos; visibility; severity= None} {issue_type; description= desc; ocaml_pos= Some ocaml_pos; severity= None}
| Deallocate_stack_variable desc -> | Deallocate_stack_variable desc ->
{ issue_type= IssueType.deallocate_stack_variable { issue_type= IssueType.deallocate_stack_variable
; description= desc ; description= desc
; ocaml_pos= None ; ocaml_pos= None
; visibility= Exn_user
; severity= None } ; severity= None }
| Deallocate_static_memory desc -> | Deallocate_static_memory desc ->
{ issue_type= IssueType.deallocate_static_memory { issue_type= IssueType.deallocate_static_memory
; description= desc ; description= desc
; ocaml_pos= None ; ocaml_pos= None
; visibility= Exn_user
; severity= None } ; severity= None }
| Deallocation_mismatch (desc, ocaml_pos) -> | Deallocation_mismatch (desc, ocaml_pos) ->
{ issue_type= IssueType.deallocation_mismatch { issue_type= IssueType.deallocation_mismatch
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Divide_by_zero (desc, ocaml_pos) -> | Divide_by_zero (desc, ocaml_pos) ->
{ issue_type= IssueType.divide_by_zero { issue_type= IssueType.divide_by_zero
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error } ; severity= Some Error }
| Empty_vector_access (desc, ocaml_pos) -> | Empty_vector_access (desc, ocaml_pos) ->
{ issue_type= IssueType.empty_vector_access { issue_type= IssueType.empty_vector_access
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error } ; severity= Some Error }
| Field_not_null_checked (desc, ocaml_pos) -> | Field_not_null_checked (desc, ocaml_pos) ->
{ issue_type= IssueType.field_not_null_checked { issue_type= IssueType.field_not_null_checked
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Warning } ; severity= Some Warning }
| Frontend_warning (issue_type, desc, ocaml_pos) -> | Frontend_warning (issue_type, desc, ocaml_pos) ->
{ issue_type {issue_type; description= desc; ocaml_pos= Some ocaml_pos; severity= None}
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Checkers (kind, desc) -> | Checkers (kind, desc) ->
{issue_type= kind; description= desc; ocaml_pos= None; visibility= Exn_user; severity= None} {issue_type= kind; description= desc; ocaml_pos= None; severity= None}
| Null_dereference (desc, ocaml_pos) -> | Null_dereference (desc, ocaml_pos) ->
{ issue_type= IssueType.null_dereference { issue_type= IssueType.null_dereference
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Null_test_after_dereference (desc, ocaml_pos) -> | Null_test_after_dereference (desc, ocaml_pos) ->
{ issue_type= IssueType.null_test_after_dereference { issue_type= IssueType.null_test_after_dereference
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Pointer_size_mismatch (desc, ocaml_pos) -> | Pointer_size_mismatch (desc, ocaml_pos) ->
{ issue_type= IssueType.pointer_size_mismatch { issue_type= IssueType.pointer_size_mismatch
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error } ; severity= Some Error }
| Inherently_dangerous_function desc -> | Inherently_dangerous_function desc ->
{ issue_type= IssueType.inherently_dangerous_function { issue_type= IssueType.inherently_dangerous_function
; description= desc ; description= desc
; ocaml_pos= None ; ocaml_pos= None
; visibility= Exn_developer
; severity= None } ; severity= None }
| Internal_error desc -> | Internal_error desc ->
{ issue_type= IssueType.internal_error {issue_type= IssueType.internal_error; description= desc; ocaml_pos= None; severity= None}
; description= desc
; ocaml_pos= None
; visibility= Exn_developer
; severity= None }
| Leak (fp_part, (user_visible, error_desc), done_array_abstraction, resource, ocaml_pos) -> | Leak (fp_part, (user_visible, error_desc), done_array_abstraction, resource, ocaml_pos) ->
if done_array_abstraction then if done_array_abstraction then
{ issue_type= IssueType.leak_after_array_abstraction { issue_type= IssueType.leak_after_array_abstraction
; description= error_desc ; description= error_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
else if fp_part then else if fp_part then
{ issue_type= IssueType.leak_in_footprint { issue_type= IssueType.leak_in_footprint
; description= error_desc ; description= error_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
else if not user_visible then else if not user_visible then
{ issue_type= IssueType.leak_unknown_origin { issue_type= IssueType.leak_unknown_origin
; description= error_desc ; description= error_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
else else
let issue_type = let issue_type =
@ -313,104 +261,82 @@ let recognize_exception exn =
| PredSymb.Rignore -> | PredSymb.Rignore ->
IssueType.memory_leak IssueType.memory_leak
in in
{ issue_type {issue_type; description= error_desc; ocaml_pos= Some ocaml_pos; severity= None}
; description= error_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Missing_fld (fld, ocaml_pos) -> | Missing_fld (fld, ocaml_pos) ->
let desc = Localise.verbatim_desc (Fieldname.to_full_string fld) in let desc = Localise.verbatim_desc (Fieldname.to_full_string fld) in
{ issue_type= IssueType.missing_fld { issue_type= IssueType.missing_fld
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Premature_nil_termination (desc, ocaml_pos) -> | Premature_nil_termination (desc, ocaml_pos) ->
{ issue_type= IssueType.premature_nil_termination { issue_type= IssueType.premature_nil_termination
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Parameter_not_null_checked (desc, ocaml_pos) -> | Parameter_not_null_checked (desc, ocaml_pos) ->
{ issue_type= IssueType.parameter_not_null_checked { issue_type= IssueType.parameter_not_null_checked
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Warning } ; severity= Some Warning }
| Precondition_not_found (desc, ocaml_pos) -> | Precondition_not_found (desc, ocaml_pos) ->
{ issue_type= IssueType.precondition_not_found { issue_type= IssueType.precondition_not_found
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Precondition_not_met (desc, ocaml_pos) -> | Precondition_not_met (desc, ocaml_pos) ->
{ issue_type= IssueType.precondition_not_met { issue_type= IssueType.precondition_not_met
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= Some Warning } ; severity= Some Warning }
(* always a warning *) (* always a warning *)
| Retain_cycle (desc, ocaml_pos) -> | Retain_cycle (desc, ocaml_pos) ->
{ issue_type= IssueType.retain_cycle { issue_type= IssueType.retain_cycle
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Registered_observer_being_deallocated (desc, ocaml_pos) -> | Registered_observer_being_deallocated (desc, ocaml_pos) ->
{ issue_type= IssueType.biabd_registered_observer_being_deallocated { issue_type= IssueType.biabd_registered_observer_being_deallocated
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error } ; severity= Some Error }
| Stack_variable_address_escape (desc, ocaml_pos) -> | Stack_variable_address_escape (desc, ocaml_pos) ->
{ issue_type= IssueType.biabd_stack_variable_address_escape { issue_type= IssueType.biabd_stack_variable_address_escape
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error } ; severity= Some Error }
| SymOp.Analysis_failure_exe _ -> | SymOp.Analysis_failure_exe _ ->
{ issue_type= IssueType.failure_exe { issue_type= IssueType.failure_exe
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= None ; ocaml_pos= None
; visibility= Exn_system
; severity= None } ; severity= None }
| Skip_function desc -> | Skip_function desc ->
{ issue_type= IssueType.skip_function {issue_type= IssueType.skip_function; description= desc; ocaml_pos= None; severity= None}
; description= desc
; ocaml_pos= None
; visibility= Exn_developer
; severity= None }
| Skip_pointer_dereference (desc, ocaml_pos) -> | Skip_pointer_dereference (desc, ocaml_pos) ->
{ issue_type= IssueType.skip_pointer_dereference { issue_type= IssueType.skip_pointer_dereference
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Info } ; severity= Some Info }
(* always an info *) (* always an info *)
| Symexec_memory_error ocaml_pos -> | Symexec_memory_error ocaml_pos ->
{ issue_type= IssueType.symexec_memory_error { issue_type= IssueType.symexec_memory_error
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| Unary_minus_applied_to_unsigned_expression (desc, ocaml_pos) -> | Unary_minus_applied_to_unsigned_expression (desc, ocaml_pos) ->
{ issue_type= IssueType.unary_minus_applied_to_unsigned_expression { issue_type= IssueType.unary_minus_applied_to_unsigned_expression
; description= desc ; description= desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None } ; severity= None }
| Wrong_argument_number ocaml_pos -> | Wrong_argument_number ocaml_pos ->
{ issue_type= IssueType.wrong_argument_number { issue_type= IssueType.wrong_argument_number
; description= Localise.no_desc ; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos ; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None } ; severity= None }
| exn -> | exn ->
{ issue_type= IssueType.failure_exe { issue_type= IssueType.failure_exe
; description= ; description=
Localise.verbatim_desc (F.asprintf "%a: %s" Exn.pp exn (Caml.Printexc.get_backtrace ())) Localise.verbatim_desc (F.asprintf "%a: %s" Exn.pp exn (Caml.Printexc.get_backtrace ()))
; ocaml_pos= None ; ocaml_pos= None
; visibility= Exn_system
; severity= None } ; severity= None }
@ -428,23 +354,12 @@ let print_exception_html s exn =
error.description ocaml_pos_string error.description ocaml_pos_string
(** string describing an error kind *)
let severity_string = function
| Advice ->
"ADVICE"
| Error ->
"ERROR"
| Info ->
"INFO"
| Like ->
"LIKE"
| Warning ->
"WARNING"
(** pretty print an error *) (** pretty print an error *)
let pp_err loc severity issue_type desc ocaml_pos_opt fmt () = let pp_err loc severity issue_type desc ocaml_pos_opt fmt () =
let kind = severity_string (if equal_severity severity Info then Warning else severity) in let kind =
IssueType.string_of_severity
(if IssueType.equal_severity severity Info then Warning else severity)
in
F.fprintf fmt "%a:%d: %s: %a %a%a@\n" SourceFile.pp loc.Location.file loc.Location.line kind F.fprintf fmt "%a:%d: %s: %a %a%a@\n" SourceFile.pp loc.Location.file loc.Location.line kind
IssueType.pp issue_type Localise.pp_error_desc desc L.pp_ocaml_pos_opt ocaml_pos_opt IssueType.pp issue_type Localise.pp_error_desc desc L.pp_ocaml_pos_opt ocaml_pos_opt
@ -452,4 +367,5 @@ let pp_err loc severity issue_type desc ocaml_pos_opt fmt () =
(** Return true if the exception is not serious and should be handled in timeout mode *) (** Return true if the exception is not serious and should be handled in timeout mode *)
let handle_exception exn = let handle_exception exn =
let error = recognize_exception exn in let error = recognize_exception exn in
equal_visibility error.visibility Exn_user || equal_visibility error.visibility Exn_developer IssueType.equal_visibility error.issue_type.visibility User
|| IssueType.equal_visibility error.issue_type.visibility Developer

@ -10,20 +10,6 @@ open! IStd
(** Functions for logging and printing exceptions *) (** Functions for logging and printing exceptions *)
(** visibility of the exception *)
type visibility =
| Exn_user (** always add to error log *)
| Exn_developer (** only add to error log in developer mode *)
| Exn_system (** never add to error log *)
[@@deriving compare]
val equal_visibility : visibility -> visibility -> bool
(** severity of the report *)
type severity = Like | Info | Advice | Warning | Error [@@deriving compare]
val equal_severity : severity -> severity -> bool
exception Abduction_case_not_implemented of Logging.ocaml_pos exception Abduction_case_not_implemented of Logging.ocaml_pos
exception Analysis_stops of Localise.error_desc * Logging.ocaml_pos option exception Analysis_stops of Localise.error_desc * Logging.ocaml_pos option
@ -48,7 +34,7 @@ exception Class_cast_exception of Localise.error_desc * Logging.ocaml_pos
exception Condition_always_true_false of Localise.error_desc * bool * Logging.ocaml_pos exception Condition_always_true_false of Localise.error_desc * bool * Logging.ocaml_pos
exception Custom_error of string * Localise.error_desc exception Custom_error of string * IssueType.severity * Localise.error_desc
exception exception
Dangling_pointer_dereference of Dangling_pointer_dereference of
@ -112,9 +98,6 @@ exception Unary_minus_applied_to_unsigned_expression of Localise.error_desc * Lo
exception Wrong_argument_number of Logging.ocaml_pos exception Wrong_argument_number of Logging.ocaml_pos
val severity_string : severity -> string
(** string describing an error kind *)
val handle_exception : exn -> bool val handle_exception : exn -> bool
(** Return true if the exception is not serious and should be handled in timeout mode *) (** Return true if the exception is not serious and should be handled in timeout mode *)
@ -123,7 +106,7 @@ val print_exception_html : string -> exn -> unit
val pp_err : val pp_err :
Location.t Location.t
-> severity -> IssueType.severity
-> IssueType.t -> IssueType.t
-> Localise.error_desc -> Localise.error_desc
-> Logging.ocaml_pos option -> Logging.ocaml_pos option
@ -136,7 +119,6 @@ type t =
{ issue_type: IssueType.t { issue_type: IssueType.t
; description: Localise.error_desc ; description: Localise.error_desc
; ocaml_pos: Logging.ocaml_pos option (** location in the infer source code *) ; ocaml_pos: Logging.ocaml_pos option (** location in the infer source code *)
; visibility: visibility ; severity: IssueType.severity option }
; severity: severity option }
val recognize_exception : exn -> t val recognize_exception : exn -> t

@ -64,13 +64,13 @@ let log_issue_from_summary_simplified severity attrs err_log ~loc ?(ltr = []) ?e
let log_error attrs err_log ~loc ?ltr ?extras checker issue_type error_message = let log_error attrs err_log ~loc ?ltr ?extras checker issue_type error_message =
log_issue_from_summary_simplified Exceptions.Error attrs err_log ~loc ?ltr ?extras checker log_issue_from_summary_simplified Error attrs err_log ~loc ?ltr ?extras checker issue_type
issue_type error_message error_message
let log_warning attrs err_log ~loc ?ltr ?extras checker issue_type error_message = let log_warning attrs err_log ~loc ?ltr ?extras checker issue_type error_message =
log_issue_from_summary_simplified Exceptions.Warning attrs err_log ~loc ?ltr ?extras checker log_issue_from_summary_simplified Warning attrs err_log ~loc ?ltr ?extras checker issue_type
issue_type error_message error_message
let log_issue_external procname ~issue_log severity ~loc ~ltr ?access ?extras checker issue_type let log_issue_external procname ~issue_log severity ~loc ~ltr ?access ?extras checker issue_type

@ -13,7 +13,7 @@ type log_t =
?ltr:Errlog.loc_trace -> ?extras:Jsonbug_t.extra -> Checker.t -> IssueType.t -> string -> unit ?ltr:Errlog.loc_trace -> ?extras:Jsonbug_t.extra -> Checker.t -> IssueType.t -> string -> unit
val log_issue_from_summary : val log_issue_from_summary :
Exceptions.severity IssueType.severity
-> Procdesc.t -> Procdesc.t
-> Errlog.t -> Errlog.t
-> node:Errlog.node -> node:Errlog.node
@ -26,7 +26,7 @@ val log_issue_from_summary :
-> unit -> unit
val log_frontend_issue : val log_frontend_issue :
Exceptions.severity IssueType.severity
-> Errlog.t -> Errlog.t
-> loc:Location.t -> loc:Location.t
-> node_key:Procdesc.NodeKey.t -> node_key:Procdesc.NodeKey.t
@ -44,7 +44,7 @@ val log_warning : Procdesc.t -> Errlog.t -> loc:Location.t -> log_t
val log_issue_external : val log_issue_external :
Procname.t Procname.t
-> issue_log:IssueLog.t -> issue_log:IssueLog.t
-> Exceptions.severity -> IssueType.severity
-> loc:Location.t -> loc:Location.t
-> ltr:Errlog.loc_trace -> ltr:Errlog.loc_trace
-> ?access:string -> ?access:string

@ -177,15 +177,15 @@ let remove_new_lines_and_whitespace message =
let string_to_severity = function let string_to_severity = function
| "WARNING" -> | "WARNING" ->
Exceptions.Warning IssueType.Warning
| "ERROR" -> | "ERROR" ->
Exceptions.Error IssueType.Error
| "INFO" -> | "INFO" ->
Exceptions.Info IssueType.Info
| "ADVICE" -> | "ADVICE" ->
Exceptions.Advice IssueType.Advice
| "LIKE" -> | "LIKE" ->
Exceptions.Like IssueType.Like
| s -> | s ->
L.die InternalError "Severity %s does not exist" s L.die InternalError "Severity %s does not exist" s
@ -209,7 +209,7 @@ type issue_in_construction =
; description: string ; description: string
; mode: CIssue.mode ; mode: CIssue.mode
; loc: Location.t ; loc: Location.t
; severity: Exceptions.severity ; severity: IssueType.severity
; suggestion: string option } ; suggestion: string option }
(** Convert a parsed checker in list of linters *) (** Convert a parsed checker in list of linters *)
@ -263,7 +263,7 @@ let create_parsed_linters linters_def_file checkers : linter list =
issue_desc.issue_type_doc_url issue_desc.issue_type_doc_url
in in
IssueType.register_from_string ~id:checker.id ?hum:issue_desc.issue_type_name ?doc_url IssueType.register_from_string ~id:checker.id ?hum:issue_desc.issue_type_name ?doc_url
~linters_def_file Linters ~linters_def_file issue_desc.severity Linters
in in
let issue_desc = let issue_desc =
{ CIssue.issue_type { CIssue.issue_type

@ -149,8 +149,8 @@ let mutable_local_vars_advice context an =
else else
Some Some
{ CIssue.issue_type= IssueType.mutable_local_variable_in_component_file { CIssue.issue_type= IssueType.mutable_local_variable_in_component_file
; severity= Exceptions.Advice ; severity= Advice
; mode= CIssue.On ; mode= On
; description= ; description=
"Local variable " "Local variable "
^ MF.monospaced_to_string named_decl_info.ni_name ^ MF.monospaced_to_string named_decl_info.ni_name
@ -181,8 +181,8 @@ let component_factory_function_advice context an =
if is_component_if objc_interface then if is_component_if objc_interface then
Some Some
{ CIssue.issue_type= IssueType.component_factory_function { CIssue.issue_type= IssueType.component_factory_function
; severity= Exceptions.Advice ; severity= Advice
; mode= CIssue.Off ; mode= Off
; description= "Break out composite components" ; description= "Break out composite components"
; suggestion= ; suggestion=
Some Some
@ -236,8 +236,8 @@ let component_with_unconventional_superclass_advice context an =
if condition then if condition then
Some Some
{ CIssue.issue_type= IssueType.component_with_unconventional_superclass { CIssue.issue_type= IssueType.component_with_unconventional_superclass
; severity= Exceptions.Advice ; severity= Advice
; mode= CIssue.On ; mode= On
; description= "Never Subclass Components" ; description= "Never Subclass Components"
; suggestion= Some "Instead, create a new subclass of CKCompositeComponent." ; suggestion= Some "Instead, create a new subclass of CKCompositeComponent."
; loc= ALUtils.location_from_decl context if_decl } ; loc= ALUtils.location_from_decl context if_decl }
@ -290,8 +290,8 @@ let component_with_multiple_factory_methods_advice context an =
List.map List.map
~f:(fun meth_decl -> ~f:(fun meth_decl ->
{ CIssue.issue_type= IssueType.component_with_multiple_factory_methods { CIssue.issue_type= IssueType.component_with_multiple_factory_methods
; severity= Exceptions.Advice ; severity= Advice
; mode= CIssue.On ; mode= On
; description= "Avoid Overrides" ; description= "Avoid Overrides"
; suggestion= ; suggestion=
Some Some
@ -367,8 +367,8 @@ let rec component_initializer_with_side_effects_advice_ (context : CLintersConte
| Some "dispatch_after" | Some "dispatch_async" | Some "dispatch_sync" -> | Some "dispatch_after" | Some "dispatch_async" | Some "dispatch_sync" ->
Some Some
{ CIssue.issue_type= IssueType.component_initializer_with_side_effects { CIssue.issue_type= IssueType.component_initializer_with_side_effects
; severity= Exceptions.Advice ; severity= Advice
; mode= CIssue.On ; mode= On
; description= "No Side-effects" ; description= "No Side-effects"
; suggestion= ; suggestion=
Some "Your +new method should not modify any global variables or global state." Some "Your +new method should not modify any global variables or global state."
@ -403,8 +403,8 @@ let component_file_line_count_info (context : CLintersContext.context) dec =
List.map List.map
~f:(fun i -> ~f:(fun i ->
{ CIssue.issue_type= IssueType.component_file_line_count { CIssue.issue_type= IssueType.component_file_line_count
; severity= Exceptions.Info ; severity= Info
; mode= CIssue.Off ; mode= Off
; description= "Line count analytics" ; description= "Line count analytics"
; suggestion= None ; suggestion= None
; loc= {Location.line= i; Location.col= 0; Location.file= source_file} } ) ; loc= {Location.line= i; Location.col= 0; Location.file= source_file} } )
@ -452,8 +452,8 @@ let component_file_cyclomatic_complexity_info (context : CLintersContext.context
| Some loc -> | Some loc ->
Some Some
{ CIssue.issue_type= IssueType.component_file_cyclomatic_complexity { CIssue.issue_type= IssueType.component_file_cyclomatic_complexity
; severity= Exceptions.Info ; severity= Info
; mode= CIssue.Off ; mode= Off
; description= "Cyclomatic Complexity Incremental Marker" ; description= "Cyclomatic Complexity Incremental Marker"
; suggestion= None ; suggestion= None
; loc } ; loc }

@ -24,13 +24,13 @@ type t =
; description: string (** Description in the error message *) ; description: string (** Description in the error message *)
; mode: mode ; mode: mode
; loc: Location.t (** location in the code *) ; loc: Location.t (** location in the code *)
; severity: Exceptions.severity ; severity: IssueType.severity
; suggestion: string option (** an optional suggestion or correction *) } ; suggestion: string option (** an optional suggestion or correction *) }
let pp fmt issue = let pp fmt issue =
Format.fprintf fmt "{@\n Id = %s@\n" issue.issue_type.IssueType.unique_id ; Format.fprintf fmt "{@\n Id = %s@\n" issue.issue_type.IssueType.unique_id ;
Format.fprintf fmt "{ Name = %s@\n" issue.issue_type.IssueType.hum ; Format.fprintf fmt "{ Name = %s@\n" issue.issue_type.IssueType.hum ;
Format.fprintf fmt " Severity = %s@\n" (Exceptions.severity_string issue.severity) ; Format.fprintf fmt " Severity = %s@\n" (IssueType.string_of_severity issue.severity) ;
Format.fprintf fmt " Mode = %s@\n" (string_of_mode issue.mode) ; Format.fprintf fmt " Mode = %s@\n" (string_of_mode issue.mode) ;
Format.fprintf fmt " Description = %s@\n" issue.description ; Format.fprintf fmt " Description = %s@\n" issue.description ;
Format.fprintf fmt " Suggestion = %s@\n" (Option.value ~default:"" issue.suggestion) ; Format.fprintf fmt " Suggestion = %s@\n" (Option.value ~default:"" issue.suggestion) ;

@ -16,7 +16,7 @@ type t =
; description: string (** Description in the error message *) ; description: string (** Description in the error message *)
; mode: mode ; mode: mode
; loc: Location.t (** location in the code *) ; loc: Location.t (** location in the code *)
; severity: Exceptions.severity ; severity: IssueType.severity
; suggestion: string option (** an optional suggestion or correction *) } ; suggestion: string option (** an optional suggestion or correction *) }
val pp : Format.formatter -> t -> unit val pp : Format.formatter -> t -> unit

@ -1185,7 +1185,7 @@ and () =
issue issue
| None -> | None ->
(* unknown issue type: assume it will be defined in AL *) (* unknown issue type: assume it will be defined in AL *)
IssueType.register_from_string ~id:issue_id Linters IssueType.register_from_string ~id:issue_id Warning Linters
in in
IssueType.set_enabled issue b ; IssueType.set_enabled issue b ;
issue_id ) issue_id )

@ -9,12 +9,33 @@ open! IStd
module F = Format module F = Format
module L = Die module L = Die
type visibility = User | Developer | Silent [@@deriving compare, equal]
let string_of_visibility = function User -> "User" | Developer -> "Developer" | Silent -> "Silent"
type severity = Like | Info | Advice | Warning | Error [@@deriving compare, equal, enumerate]
let string_of_severity = function
| Advice ->
"ADVICE"
| Error ->
"ERROR"
| Info ->
"INFO"
| Like ->
"LIKE"
| Warning ->
"WARNING"
(* Make sure we cannot create new issue types other than by calling [register_from_string]. This is because (* Make sure we cannot create new issue types other than by calling [register_from_string]. This is because
we want to keep track of the list of all the issues ever declared. *) we want to keep track of the list of all the issues ever declared. *)
module Unsafe : sig module Unsafe : sig
type t = private type t = private
{ unique_id: string { unique_id: string
; checker: Checker.t ; checker: Checker.t
; visibility: visibility
; mutable default_severity: severity
; mutable enabled: bool ; mutable enabled: bool
; mutable hum: string ; mutable hum: string
; mutable doc_url: string option ; mutable doc_url: string option
@ -33,6 +54,8 @@ module Unsafe : sig
-> ?doc_url:string -> ?doc_url:string
-> ?linters_def_file:string -> ?linters_def_file:string
-> id:string -> id:string
-> ?visibility:visibility
-> severity
-> Checker.t -> Checker.t
-> t -> t
@ -51,6 +74,8 @@ end = struct
type t = type t =
{ unique_id: string { unique_id: string
; checker: Checker.t ; checker: Checker.t
; visibility: visibility
; mutable default_severity: severity
; mutable enabled: bool ; mutable enabled: bool
; mutable hum: string ; mutable hum: string
; mutable doc_url: string option ; mutable doc_url: string option
@ -94,29 +119,42 @@ end = struct
definitely. The [hum]an-readable description can be updated when we encounter the definition definitely. The [hum]an-readable description can be updated when we encounter the definition
of the issue type, eg in AL. *) of the issue type, eg in AL. *)
let register_from_string ?(enabled = true) ?hum:hum0 ?doc_url ?linters_def_file ~id:unique_id let register_from_string ?(enabled = true) ?hum:hum0 ?doc_url ?linters_def_file ~id:unique_id
checker = ?(visibility = User) default_severity checker =
match find_from_string ~id:unique_id with match find_from_string ~id:unique_id with
| ((Some | ((Some
( { unique_id= _ (* we know it has to be the same *) ( { unique_id= _ (* we know it has to be the same *)
; checker= checker_old ; checker= checker_old
; visibility= visibility_old
; default_severity= _ (* mutable field to update *)
; enabled= _ (* not touching this one since [Config] will have set it *) ; enabled= _ (* not touching this one since [Config] will have set it *)
; hum= _ (* mutable field to update *) ; hum= _ (* mutable field to update *)
; doc_url= _ (* mutable field to update *) ; doc_url= _ (* mutable field to update *)
; linters_def_file= _ (* mutable field to update *) } as issue ))[@warning "+9"]) -> ; linters_def_file= _ (* mutable field to update *) } as issue ))[@warning "+9"]) ->
(* update fields that were supplied this time around, but keep the previous values of others (* update fields that were supplied this time around, but keep the previous values of others
and assert that the immutable fields are the same (see doc comment) *) and assert that the immutable fields are the same (see doc comment) *)
if not (Checker.equal checker checker_old) then let die_of_mismatch ~what ~old ~new_ =
L.die InternalError L.die InternalError
"Checker definition for issue \"%s\" doesn't match: found new checker \"%s\" but \ "%s for issue \"%s\" doesn't match: found new %s \"%s\" but %s \"%s\" was already \
checker \"%s\" was already registered for this issue type" registered for this issue type"
unique_id (Checker.get_name checker) (Checker.get_name checker_old) ; (String.capitalize what) unique_id what new_ what old
in
if not (Checker.equal checker checker_old) then
die_of_mismatch ~what:"checker" ~old:(Checker.get_name checker_old)
~new_:(Checker.get_name checker) ;
if not (equal_visibility visibility visibility_old) then
die_of_mismatch ~what:"visibility"
~old:(string_of_visibility visibility_old)
~new_:(string_of_visibility visibility) ;
issue.default_severity <- default_severity ;
Option.iter hum0 ~f:(fun hum -> issue.hum <- hum) ; Option.iter hum0 ~f:(fun hum -> issue.hum <- hum) ;
if Option.is_some doc_url then issue.doc_url <- doc_url ; if Option.is_some doc_url then issue.doc_url <- doc_url ;
if Option.is_some linters_def_file then issue.linters_def_file <- linters_def_file ; if Option.is_some linters_def_file then issue.linters_def_file <- linters_def_file ;
issue issue
| None -> | None ->
let hum = match hum0 with Some str -> str | _ -> prettify unique_id in let hum = match hum0 with Some str -> str | _ -> prettify unique_id in
let issue = {unique_id; checker; enabled; hum; doc_url; linters_def_file} in let issue =
{unique_id; visibility; default_severity; checker; enabled; hum; doc_url; linters_def_file}
in
all_issues := IssueSet.add !all_issues issue ; all_issues := IssueSet.add !all_issues issue ;
issue issue
@ -126,7 +164,7 @@ end = struct
= =
let issue_type_base = F.asprintf s (CostKind.to_issue_string kind) in let issue_type_base = F.asprintf s (CostKind.to_issue_string kind) in
let issue_type = if is_on_ui_thread then issue_type_base ^ "_UI_THREAD" else issue_type_base in let issue_type = if is_on_ui_thread then issue_type_base ^ "_UI_THREAD" else issue_type_base in
register_from_string ~enabled ~id:issue_type Cost register_from_string ~enabled ~id:issue_type Error Cost
let all_issues () = IssueSet.elements !all_issues let all_issues () = IssueSet.elements !all_issues
@ -139,249 +177,279 @@ let checker_can_report reporting_checker {checker= allowed_checker} =
let abduction_case_not_implemented = let abduction_case_not_implemented =
register_from_string ~id:"Abduction_case_not_implemented" Biabduction register_from_string ~visibility:Developer ~id:"Abduction_case_not_implemented" Error Biabduction
let array_of_pointsto =
register_from_string ~visibility:Developer ~id:"Array_of_pointsto" Error Biabduction
let array_of_pointsto = register_from_string ~id:"Array_of_pointsto" Biabduction
let array_out_of_bounds_l1 = let array_out_of_bounds_l1 =
register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L1" Biabduction register_from_string ~visibility:Developer ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L1" Error
Biabduction
let array_out_of_bounds_l2 = let array_out_of_bounds_l2 =
register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L2" Biabduction register_from_string ~visibility:Developer ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L2" Warning
Biabduction
let array_out_of_bounds_l3 = let array_out_of_bounds_l3 =
register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L3" Biabduction register_from_string ~visibility:Developer ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L3" Warning
Biabduction
let assert_failure = register_from_string ~id:"Assert_failure" Biabduction let assert_failure =
register_from_string ~visibility:Developer ~id:"Assert_failure" Error Biabduction
let bad_footprint = register_from_string ~id:"Bad_footprint" Biabduction
let bad_footprint = register_from_string ~visibility:Developer ~id:"Bad_footprint" Error Biabduction
let biabduction_analysis_stops = let biabduction_analysis_stops =
register_from_string ~enabled:false ~id:"BIABDUCTION_ANALYSIS_STOPS" Biabduction register_from_string ~visibility:Developer ~enabled:false ~id:"BIABDUCTION_ANALYSIS_STOPS" Warning
Biabduction
let biabd_condition_always_false = let biabd_condition_always_false =
register_from_string ~enabled:false ~hum:"Condition Always False" register_from_string ~enabled:false ~hum:"Condition Always False"
~id:"BIABD_CONDITION_ALWAYS_FALSE" Biabduction ~id:"BIABD_CONDITION_ALWAYS_FALSE" Warning Biabduction
let biabd_condition_always_true = let biabd_condition_always_true =
register_from_string ~enabled:false ~hum:"Condition Always True" ~id:"BIABD_CONDITION_ALWAYS_TRUE" register_from_string ~enabled:false ~hum:"Condition Always True" ~id:"BIABD_CONDITION_ALWAYS_TRUE"
Biabduction Warning Biabduction
let biabd_registered_observer_being_deallocated = let biabd_registered_observer_being_deallocated =
register_from_string ~hum:"Registered Observer Being Deallocated" register_from_string ~hum:"Registered Observer Being Deallocated"
~id:"BIABD_REGISTERED_OBSERVER_BEING_DEALLOCATED" Biabduction ~id:"BIABD_REGISTERED_OBSERVER_BEING_DEALLOCATED" Error Biabduction
let biabd_stack_variable_address_escape = let biabd_stack_variable_address_escape =
register_from_string ~enabled:false ~hum:"Stack Variable Address Escape" register_from_string ~enabled:false ~hum:"Stack Variable Address Escape"
~id:"BIABD_STACK_VARIABLE_ADDRESS_ESCAPE" Biabduction ~id:"BIABD_STACK_VARIABLE_ADDRESS_ESCAPE" Error Biabduction
let biabd_use_after_free = let biabd_use_after_free =
register_from_string ~hum:"Use After Free" ~id:"BIABD_USE_AFTER_FREE" Biabduction register_from_string ~hum:"Use After Free" ~id:"BIABD_USE_AFTER_FREE" Error Biabduction
let buffer_overrun_l1 = register_from_string ~id:"BUFFER_OVERRUN_L1" BufferOverrunChecker let buffer_overrun_l1 = register_from_string ~id:"BUFFER_OVERRUN_L1" Error BufferOverrunChecker
let buffer_overrun_l2 = register_from_string ~id:"BUFFER_OVERRUN_L2" BufferOverrunChecker let buffer_overrun_l2 = register_from_string ~id:"BUFFER_OVERRUN_L2" Error BufferOverrunChecker
let buffer_overrun_l3 = register_from_string ~id:"BUFFER_OVERRUN_L3" BufferOverrunChecker let buffer_overrun_l3 = register_from_string ~id:"BUFFER_OVERRUN_L3" Error BufferOverrunChecker
let buffer_overrun_l4 = let buffer_overrun_l4 =
register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L4" BufferOverrunChecker register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L4" Error BufferOverrunChecker
let buffer_overrun_l5 = let buffer_overrun_l5 =
register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L5" BufferOverrunChecker register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L5" Error BufferOverrunChecker
let buffer_overrun_r2 = register_from_string ~id:"BUFFER_OVERRUN_R2" BufferOverrunChecker let buffer_overrun_r2 = register_from_string ~id:"BUFFER_OVERRUN_R2" Error BufferOverrunChecker
let buffer_overrun_s2 = register_from_string ~id:"BUFFER_OVERRUN_S2" BufferOverrunChecker let buffer_overrun_s2 = register_from_string ~id:"BUFFER_OVERRUN_S2" Error BufferOverrunChecker
let buffer_overrun_t1 = register_from_string ~id:"BUFFER_OVERRUN_T1" BufferOverrunChecker let buffer_overrun_t1 = register_from_string ~id:"BUFFER_OVERRUN_T1" Error BufferOverrunChecker
let buffer_overrun_u5 = let buffer_overrun_u5 =
register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_U5" BufferOverrunChecker register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_U5" Error BufferOverrunChecker
let cannot_star = register_from_string ~id:"Cannot_star" Biabduction let cannot_star = register_from_string ~visibility:Developer ~id:"Cannot_star" Error Biabduction
let captured_strong_self = let captured_strong_self =
register_from_string ~id:"CAPTURED_STRONG_SELF" ~hum:"Captured strongSelf" SelfInBlock register_from_string ~id:"CAPTURED_STRONG_SELF" ~hum:"Captured strongSelf" Error SelfInBlock
let checkers_allocates_memory = let checkers_allocates_memory =
register_from_string ~id:"CHECKERS_ALLOCATES_MEMORY" ~hum:"Allocates Memory" register_from_string ~id:"CHECKERS_ALLOCATES_MEMORY" ~hum:"Allocates Memory" Error
AnnotationReachability AnnotationReachability
let checkers_annotation_reachability_error = let checkers_annotation_reachability_error =
register_from_string ~id:"CHECKERS_ANNOTATION_REACHABILITY_ERROR" register_from_string ~id:"CHECKERS_ANNOTATION_REACHABILITY_ERROR"
~hum:"Annotation Reachability Error" AnnotationReachability ~hum:"Annotation Reachability Error" Error AnnotationReachability
let checkers_calls_expensive_method = let checkers_calls_expensive_method =
register_from_string ~id:"CHECKERS_CALLS_EXPENSIVE_METHOD" ~hum:"Expensive Method Called" register_from_string ~id:"CHECKERS_CALLS_EXPENSIVE_METHOD" ~hum:"Expensive Method Called" Error
AnnotationReachability AnnotationReachability
let checkers_expensive_overrides_unexpensive = let checkers_expensive_overrides_unexpensive =
register_from_string ~id:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED" register_from_string ~id:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED"
~hum:"Expensive Overrides Unannotated" AnnotationReachability ~hum:"Expensive Overrides Unannotated" Error AnnotationReachability
let checkers_fragment_retain_view = let checkers_fragment_retain_view =
register_from_string ~id:"CHECKERS_FRAGMENT_RETAINS_VIEW" ~hum:"Fragment Retains View" register_from_string ~id:"CHECKERS_FRAGMENT_RETAINS_VIEW" ~hum:"Fragment Retains View" Warning
FragmentRetainsView FragmentRetainsView
let checkers_immutable_cast = register_from_string ~id:"CHECKERS_IMMUTABLE_CAST" ImmutableCast let checkers_immutable_cast =
register_from_string ~id:"CHECKERS_IMMUTABLE_CAST" Warning ImmutableCast
let checkers_printf_args = register_from_string ~id:"CHECKERS_PRINTF_ARGS" PrintfArgs
let checkers_printf_args = register_from_string ~id:"CHECKERS_PRINTF_ARGS" Error PrintfArgs
let class_cast_exception = let class_cast_exception =
register_from_string ~enabled:false ~id:"CLASS_CAST_EXCEPTION" Biabduction register_from_string ~visibility:Developer ~enabled:false ~id:"CLASS_CAST_EXCEPTION" Error
Biabduction
let class_load = register_from_string ~id:"CLASS_LOAD" ClassLoads let class_load = register_from_string ~id:"CLASS_LOAD" Warning ClassLoads
let component_factory_function =
register_from_string ~id:"COMPONENT_FACTORY_FUNCTION" Advice Linters
let component_factory_function = register_from_string ~id:"COMPONENT_FACTORY_FUNCTION" Linters
let component_file_cyclomatic_complexity = let component_file_cyclomatic_complexity =
register_from_string ~id:"COMPONENT_FILE_CYCLOMATIC_COMPLEXITY" Linters register_from_string ~id:"COMPONENT_FILE_CYCLOMATIC_COMPLEXITY" Info Linters
let component_file_line_count = let component_file_line_count =
register_from_string ~enabled:false ~id:"COMPONENT_FILE_LINE_COUNT" Linters register_from_string ~enabled:false ~id:"COMPONENT_FILE_LINE_COUNT" Info Linters
let component_initializer_with_side_effects = let component_initializer_with_side_effects =
register_from_string ~id:"COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS" Linters register_from_string ~id:"COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS" Advice Linters
let component_with_multiple_factory_methods = let component_with_multiple_factory_methods =
register_from_string ~id:"COMPONENT_WITH_MULTIPLE_FACTORY_METHODS" Linters register_from_string ~id:"COMPONENT_WITH_MULTIPLE_FACTORY_METHODS" Advice Linters
let component_with_unconventional_superclass = let component_with_unconventional_superclass =
register_from_string ~id:"COMPONENT_WITH_UNCONVENTIONAL_SUPERCLASS" Linters register_from_string ~id:"COMPONENT_WITH_UNCONVENTIONAL_SUPERCLASS" Advice Linters
let condition_always_false = let condition_always_false =
register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_FALSE" BufferOverrunChecker register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_FALSE" Warning BufferOverrunChecker
let condition_always_true = let condition_always_true =
register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_TRUE" BufferOverrunChecker register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_TRUE" Warning BufferOverrunChecker
let constant_address_dereference = let constant_address_dereference =
register_from_string ~enabled:false ~id:"CONSTANT_ADDRESS_DEREFERENCE" Pulse register_from_string ~enabled:false ~id:"CONSTANT_ADDRESS_DEREFERENCE" Warning Pulse
let create_intent_from_uri = register_from_string ~id:"CREATE_INTENT_FROM_URI" Quandary let create_intent_from_uri = register_from_string ~id:"CREATE_INTENT_FROM_URI" Error Quandary
let cross_site_scripting = register_from_string ~id:"CROSS_SITE_SCRIPTING" Quandary let cross_site_scripting = register_from_string ~id:"CROSS_SITE_SCRIPTING" Error Quandary
let dangling_pointer_dereference = let dangling_pointer_dereference =
register_from_string ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE" Biabduction register_from_string ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE" Error Biabduction
let dangling_pointer_dereference_maybe = let dangling_pointer_dereference_maybe =
register_from_string ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE_MAYBE" Biabduction register_from_string ~visibility:Developer ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE_MAYBE"
Warning Biabduction
let dead_store = register_from_string ~id:"DEAD_STORE" Error Liveness
let deadlock = register_from_string ~id:"DEADLOCK" Error Starvation
let dead_store = register_from_string ~id:"DEAD_STORE" Liveness let deallocate_stack_variable =
register_from_string ~id:"DEALLOCATE_STACK_VARIABLE" Error Biabduction
let deadlock = register_from_string ~id:"DEADLOCK" Starvation
let deallocate_stack_variable = register_from_string ~id:"DEALLOCATE_STACK_VARIABLE" Biabduction let deallocate_static_memory = register_from_string ~id:"DEALLOCATE_STATIC_MEMORY" Error Biabduction
let deallocate_static_memory = register_from_string ~id:"DEALLOCATE_STATIC_MEMORY" Biabduction let deallocation_mismatch = register_from_string ~id:"DEALLOCATION_MISMATCH" Error Biabduction
let deallocation_mismatch = register_from_string ~id:"DEALLOCATION_MISMATCH" Biabduction let divide_by_zero = register_from_string ~enabled:false ~id:"DIVIDE_BY_ZERO" Error Biabduction
let divide_by_zero = register_from_string ~enabled:false ~id:"DIVIDE_BY_ZERO" Biabduction let do_not_report = register_from_string ~id:"DO_NOT_REPORT" Error Quandary
let do_not_report = register_from_string ~id:"DO_NOT_REPORT" Quandary let empty_vector_access = register_from_string ~id:"EMPTY_VECTOR_ACCESS" Error Biabduction
let empty_vector_access = register_from_string ~id:"EMPTY_VECTOR_ACCESS" Biabduction (* Condition redundant is a very non-precise issue. Depending on the origin of what is compared with
null, this can have a lot of reasons to be actually nullable.
Until it is made non-precise, it is recommended to not turn this warning on. But even when it is
on, this should not be more than advice. *)
let eradicate_condition_redundant = let eradicate_condition_redundant =
register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT" ~hum:"Condition Redundant" Eradicate register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT" ~hum:"Condition Redundant" Advice
Eradicate
(* TODO(T54070503) remove condition redundant nonnull *) (* TODO(T54070503) remove condition redundant nonnull *)
let _ = let _ =
register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT_NONNULL" register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT_NONNULL"
~hum:"Condition Redundant Non-Null" Eradicate ~hum:"Condition Redundant Non-Null" Warning Eradicate
let eradicate_field_not_initialized = let eradicate_field_not_initialized =
register_from_string ~id:"ERADICATE_FIELD_NOT_INITIALIZED" ~hum:"Field Not Initialized" Eradicate register_from_string ~id:"ERADICATE_FIELD_NOT_INITIALIZED" ~hum:"Field Not Initialized" Warning
Eradicate
let eradicate_field_not_nullable = let eradicate_field_not_nullable =
register_from_string ~id:"ERADICATE_FIELD_NOT_NULLABLE" ~hum:"Field Not Nullable" Eradicate register_from_string ~id:"ERADICATE_FIELD_NOT_NULLABLE" ~hum:"Field Not Nullable" Warning
Eradicate
(* Very non-precise issue. Should be actually turned off unless for experimental purposes. *)
let eradicate_field_over_annotated = let eradicate_field_over_annotated =
register_from_string ~id:"ERADICATE_FIELD_OVER_ANNOTATED" ~hum:"Field Over Annotated" Eradicate register_from_string ~id:"ERADICATE_FIELD_OVER_ANNOTATED" ~hum:"Field Over Annotated" Advice
Eradicate
let eradicate_inconsistent_subclass_parameter_annotation = let eradicate_inconsistent_subclass_parameter_annotation =
register_from_string ~id:"ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION" register_from_string ~id:"ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION"
~hum:"Inconsistent Subclass Parameter Annotation" Eradicate ~hum:"Inconsistent Subclass Parameter Annotation" Warning Eradicate
let eradicate_inconsistent_subclass_return_annotation = let eradicate_inconsistent_subclass_return_annotation =
register_from_string ~id:"ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION" register_from_string ~id:"ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION"
~hum:"Inconsistent Subclass Return Annotation" Eradicate ~hum:"Inconsistent Subclass Return Annotation" Warning Eradicate
let eradicate_redundant_nested_class_annotation = let eradicate_redundant_nested_class_annotation =
register_from_string ~id:"ERADICATE_REDUNDANT_NESTED_CLASS_ANNOTATION" register_from_string ~id:"ERADICATE_REDUNDANT_NESTED_CLASS_ANNOTATION"
~hum:"@Nullsafe annotation is redundant" Eradicate ~hum:"@Nullsafe annotation is redundant" Advice Eradicate
let eradicate_bad_nested_class_annotation = let eradicate_bad_nested_class_annotation =
register_from_string ~id:"ERADICATE_BAD_NESTED_CLASS_ANNOTATION" register_from_string ~id:"ERADICATE_BAD_NESTED_CLASS_ANNOTATION"
~hum:"@Nullsafe annotation is inconsistent with outer class" Eradicate ~hum:"@Nullsafe annotation is inconsistent with outer class" Warning Eradicate
let eradicate_nullable_dereference = let eradicate_nullable_dereference =
register_from_string ~id:"ERADICATE_NULLABLE_DEREFERENCE" ~hum:"Nullable Dereference" Eradicate register_from_string ~id:"ERADICATE_NULLABLE_DEREFERENCE" ~hum:"Nullable Dereference" Warning
Eradicate
let eradicate_parameter_not_nullable = let eradicate_parameter_not_nullable =
register_from_string ~id:"ERADICATE_PARAMETER_NOT_NULLABLE" ~hum:"Parameter Not Nullable" register_from_string ~id:"ERADICATE_PARAMETER_NOT_NULLABLE" ~hum:"Parameter Not Nullable" Warning
Eradicate Eradicate
let eradicate_return_not_nullable = let eradicate_return_not_nullable =
register_from_string ~id:"ERADICATE_RETURN_NOT_NULLABLE" ~hum:"Return Not Nullable" Eradicate register_from_string ~id:"ERADICATE_RETURN_NOT_NULLABLE" ~hum:"Return Not Nullable" Warning
Eradicate
(* Very non-precise issue. Should be actually turned off unless for experimental purposes. *)
let eradicate_return_over_annotated = let eradicate_return_over_annotated =
register_from_string ~id:"ERADICATE_RETURN_OVER_ANNOTATED" ~hum:"Return Over Annotated" Eradicate register_from_string ~id:"ERADICATE_RETURN_OVER_ANNOTATED" ~hum:"Return Over Annotated" Advice
Eradicate
let eradicate_unchecked_usage_in_nullsafe = let eradicate_unchecked_usage_in_nullsafe =
register_from_string ~id:"ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE" register_from_string ~id:"ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE"
~hum:"Nullsafe mode: unchecked usage of a value" Eradicate ~hum:"Nullsafe mode: unchecked usage of a value" Warning Eradicate
let eradicate_unvetted_third_party_in_nullsafe = let eradicate_unvetted_third_party_in_nullsafe =
register_from_string ~id:"ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE" register_from_string ~id:"ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE"
~hum:"Nullsafe mode: unchecked usage of unvetted third-party" Eradicate ~hum:"Nullsafe mode: unchecked usage of unvetted third-party" Warning Eradicate
(* Meta issues in eradicate are technical issues reflecting null-safety state of classes in general, (* Meta issues in eradicate are technical issues reflecting null-safety state of classes in general,
@ -391,7 +459,7 @@ let eradicate_meta_class_is_nullsafe =
register_from_string ~id:"ERADICATE_META_CLASS_IS_NULLSAFE" register_from_string ~id:"ERADICATE_META_CLASS_IS_NULLSAFE"
~hum: ~hum:
"Class is marked @Nullsafe and has 0 issues" (* Should be enabled for special integrations *) "Class is marked @Nullsafe and has 0 issues" (* Should be enabled for special integrations *)
~enabled:false Eradicate ~enabled:false Info Eradicate
(* Class is either: (* Class is either:
@ -402,256 +470,287 @@ let eradicate_meta_class_needs_improvement =
register_from_string ~id:"ERADICATE_META_CLASS_NEEDS_IMPROVEMENT" register_from_string ~id:"ERADICATE_META_CLASS_NEEDS_IMPROVEMENT"
~hum: ~hum:
"Class needs improvement to become @Nullsafe" (* Should be enabled for special integrations *) "Class needs improvement to become @Nullsafe" (* Should be enabled for special integrations *)
~enabled:false Eradicate ~enabled:false Info Eradicate
let eradicate_meta_class_can_be_nullsafe = let eradicate_meta_class_can_be_nullsafe =
register_from_string ~id:"ERADICATE_META_CLASS_CAN_BE_NULLSAFE" register_from_string ~id:"ERADICATE_META_CLASS_CAN_BE_NULLSAFE"
~hum: ~hum:
"Class has 0 issues and can be marked @Nullsafe" "Class has 0 issues and can be marked @Nullsafe"
(* Should be enabled for special integrations *) ~enabled:false Eradicate (* Should be enabled for special integrations *) ~enabled:false Advice Eradicate
let exposed_insecure_intent_handling = let exposed_insecure_intent_handling =
register_from_string ~id:"EXPOSED_INSECURE_INTENT_HANDLING" Quandary register_from_string ~id:"EXPOSED_INSECURE_INTENT_HANDLING" Error Quandary
let failure_exe = register_from_string ~id:"Failure_exe" Biabduction let failure_exe = register_from_string ~visibility:Silent ~id:"Failure_exe" Info Biabduction
let field_not_null_checked = register_from_string ~id:"IVAR_NOT_NULL_CHECKED" Biabduction let field_not_null_checked = register_from_string ~id:"IVAR_NOT_NULL_CHECKED" Warning Biabduction
(* from AL default linters *) (* from AL default linters *)
let _global_variable_initialized_with_function_or_method_call = let _global_variable_initialized_with_function_or_method_call =
register_from_string ~enabled:false ~id:"GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL" register_from_string ~enabled:false ~id:"GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL"
Linters Warning Linters
let guardedby_violation_racerd = let guardedby_violation_racerd =
register_from_string ~id:"GUARDEDBY_VIOLATION" ~hum:"GuardedBy Violation" RacerD register_from_string Warning ~id:"GUARDEDBY_VIOLATION" ~hum:"GuardedBy Violation" RacerD
let impure_function = register_from_string ~id:"IMPURE_FUNCTION" Impurity let impure_function = register_from_string ~id:"IMPURE_FUNCTION" Error Impurity
let inefficient_keyset_iterator = let inefficient_keyset_iterator =
register_from_string ~id:"INEFFICIENT_KEYSET_ITERATOR" InefficientKeysetIterator register_from_string ~id:"INEFFICIENT_KEYSET_ITERATOR" Error InefficientKeysetIterator
let inferbo_alloc_is_big =
register_from_string ~id:"INFERBO_ALLOC_IS_BIG" Error BufferOverrunChecker
let inferbo_alloc_is_big = register_from_string ~id:"INFERBO_ALLOC_IS_BIG" BufferOverrunChecker
let inferbo_alloc_is_negative = let inferbo_alloc_is_negative =
register_from_string ~id:"INFERBO_ALLOC_IS_NEGATIVE" BufferOverrunChecker register_from_string ~id:"INFERBO_ALLOC_IS_NEGATIVE" Error BufferOverrunChecker
let inferbo_alloc_is_zero = register_from_string ~id:"INFERBO_ALLOC_IS_ZERO" BufferOverrunChecker let inferbo_alloc_is_zero =
register_from_string ~id:"INFERBO_ALLOC_IS_ZERO" Error BufferOverrunChecker
let inferbo_alloc_may_be_big = let inferbo_alloc_may_be_big =
register_from_string ~id:"INFERBO_ALLOC_MAY_BE_BIG" BufferOverrunChecker register_from_string ~id:"INFERBO_ALLOC_MAY_BE_BIG" Error BufferOverrunChecker
let inferbo_alloc_may_be_negative = let inferbo_alloc_may_be_negative =
register_from_string ~id:"INFERBO_ALLOC_MAY_BE_NEGATIVE" BufferOverrunChecker register_from_string ~id:"INFERBO_ALLOC_MAY_BE_NEGATIVE" Error BufferOverrunChecker
let inferbo_alloc_may_be_tainted = let inferbo_alloc_may_be_tainted =
register_from_string ~id:"INFERBO_ALLOC_MAY_BE_TAINTED" BufferOverrunChecker register_from_string ~id:"INFERBO_ALLOC_MAY_BE_TAINTED" Error BufferOverrunChecker
let infinite_cost_call ~kind = register_from_cost_string ~enabled:false "INFINITE_%s" ~kind let infinite_cost_call ~kind = register_from_cost_string ~enabled:false "INFINITE_%s" ~kind
let inherently_dangerous_function = let inherently_dangerous_function =
register_from_string ~id:"INHERENTLY_DANGEROUS_FUNCTION" Biabduction register_from_string ~visibility:Developer ~id:"INHERENTLY_DANGEROUS_FUNCTION" Warning Biabduction
let insecure_intent_handling = register_from_string ~id:"INSECURE_INTENT_HANDLING" Quandary let insecure_intent_handling = register_from_string ~id:"INSECURE_INTENT_HANDLING" Error Quandary
let integer_overflow_l1 = register_from_string ~id:"INTEGER_OVERFLOW_L1" BufferOverrunChecker let integer_overflow_l1 = register_from_string ~id:"INTEGER_OVERFLOW_L1" Error BufferOverrunChecker
let integer_overflow_l2 = register_from_string ~id:"INTEGER_OVERFLOW_L2" BufferOverrunChecker let integer_overflow_l2 = register_from_string ~id:"INTEGER_OVERFLOW_L2" Error BufferOverrunChecker
let integer_overflow_l5 = let integer_overflow_l5 =
register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_L5" BufferOverrunChecker register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_L5" Error BufferOverrunChecker
let integer_overflow_r2 = register_from_string ~id:"INTEGER_OVERFLOW_R2" BufferOverrunChecker let integer_overflow_r2 = register_from_string ~id:"INTEGER_OVERFLOW_R2" Error BufferOverrunChecker
let integer_overflow_u5 = let integer_overflow_u5 =
register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_U5" BufferOverrunChecker register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_U5" Error BufferOverrunChecker
let interface_not_thread_safe = register_from_string Warning ~id:"INTERFACE_NOT_THREAD_SAFE" RacerD
let interface_not_thread_safe = register_from_string ~id:"INTERFACE_NOT_THREAD_SAFE" RacerD let internal_error =
register_from_string ~visibility:Developer ~id:"Internal_error" Error Biabduction
let internal_error = register_from_string ~id:"Internal_error" Biabduction
let invariant_call = register_from_string ~enabled:false ~id:"INVARIANT_CALL" LoopHoisting let invariant_call = register_from_string ~enabled:false ~id:"INVARIANT_CALL" Error LoopHoisting
let javascript_injection = register_from_string ~id:"JAVASCRIPT_INJECTION" Quandary let javascript_injection = register_from_string ~id:"JAVASCRIPT_INJECTION" Error Quandary
let lab_resource_leak = register_from_string ~id:"LAB_RESOURCE_LEAK" ResourceLeakLabExercise let lab_resource_leak = register_from_string ~id:"LAB_RESOURCE_LEAK" Error ResourceLeakLabExercise
let leak_after_array_abstraction = let leak_after_array_abstraction =
register_from_string ~id:"Leak_after_array_abstraction" Biabduction register_from_string ~visibility:Developer ~id:"Leak_after_array_abstraction" Error Biabduction
let leak_in_footprint =
register_from_string ~visibility:Developer ~id:"Leak_in_footprint" Error Biabduction
let leak_in_footprint = register_from_string ~id:"Leak_in_footprint" Biabduction
let leak_unknown_origin = register_from_string ~enabled:false ~id:"Leak_unknown_origin" Biabduction let leak_unknown_origin =
register_from_string ~visibility:Developer ~enabled:false ~id:"Leak_unknown_origin" Error
Biabduction
let lock_consistency_violation = register_from_string ~id:"LOCK_CONSISTENCY_VIOLATION" RacerD let lock_consistency_violation =
register_from_string Warning ~id:"LOCK_CONSISTENCY_VIOLATION" RacerD
let lockless_violation = register_from_string ~id:"LOCKLESS_VIOLATION" Starvation
let logging_private_data = register_from_string ~id:"LOGGING_PRIVATE_DATA" Quandary let lockless_violation = register_from_string ~id:"LOCKLESS_VIOLATION" Error Starvation
let logging_private_data = register_from_string ~id:"LOGGING_PRIVATE_DATA" Error Quandary
let expensive_loop_invariant_call = let expensive_loop_invariant_call =
register_from_string ~id:"EXPENSIVE_LOOP_INVARIANT_CALL" LoopHoisting register_from_string ~id:"EXPENSIVE_LOOP_INVARIANT_CALL" Error LoopHoisting
let memory_leak = register_from_string ~id:"MEMORY_LEAK" Error Biabduction
let memory_leak = register_from_string ~id:"MEMORY_LEAK" Biabduction let missing_fld =
register_from_string ~visibility:Developer ~id:"Missing_fld" ~hum:"Missing Field" Error
Biabduction
let missing_fld = register_from_string ~id:"Missing_fld" ~hum:"Missing Field" Biabduction
let missing_required_prop = register_from_string ~id:"MISSING_REQUIRED_PROP" LithoRequiredProps let missing_required_prop =
register_from_string ~id:"MISSING_REQUIRED_PROP" Error LithoRequiredProps
let mixed_self_weakself = let mixed_self_weakself =
register_from_string ~id:"MIXED_SELF_WEAKSELF" ~hum:"Mixed Self WeakSelf" SelfInBlock register_from_string ~id:"MIXED_SELF_WEAKSELF" ~hum:"Mixed Self WeakSelf" Error SelfInBlock
let multiple_weakself = let multiple_weakself =
register_from_string ~id:"MULTIPLE_WEAKSELF" ~hum:"Multiple WeakSelf Use" SelfInBlock register_from_string ~id:"MULTIPLE_WEAKSELF" ~hum:"Multiple WeakSelf Use" Error SelfInBlock
let mutable_local_variable_in_component_file = let mutable_local_variable_in_component_file =
register_from_string ~id:"MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE" Linters register_from_string ~id:"MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE" Advice Linters
let null_dereference = register_from_string ~id:"NULL_DEREFERENCE" Biabduction let null_dereference = register_from_string ~id:"NULL_DEREFERENCE" Error Biabduction
let null_test_after_dereference = let null_test_after_dereference =
register_from_string ~enabled:false ~id:"NULL_TEST_AFTER_DEREFERENCE" Biabduction register_from_string ~enabled:false ~id:"NULL_TEST_AFTER_DEREFERENCE" Warning Biabduction
let nullptr_dereference = register_from_string ~enabled:false ~id:"NULLPTR_DEREFERENCE" Error Pulse
let nullptr_dereference = register_from_string ~enabled:false ~id:"NULLPTR_DEREFERENCE" Pulse let parameter_not_null_checked =
register_from_string ~id:"PARAMETER_NOT_NULL_CHECKED" Warning Biabduction
let parameter_not_null_checked = register_from_string ~id:"PARAMETER_NOT_NULL_CHECKED" Biabduction
let pointer_size_mismatch = register_from_string ~id:"POINTER_SIZE_MISMATCH" Biabduction let pointer_size_mismatch = register_from_string ~id:"POINTER_SIZE_MISMATCH" Error Biabduction
let precondition_not_found = register_from_string ~id:"PRECONDITION_NOT_FOUND" Biabduction let precondition_not_found =
register_from_string ~visibility:Developer ~id:"PRECONDITION_NOT_FOUND" Error Biabduction
let precondition_not_met =
register_from_string ~visibility:Developer ~id:"PRECONDITION_NOT_MET" Warning Biabduction
let precondition_not_met = register_from_string ~id:"PRECONDITION_NOT_MET" Biabduction
let premature_nil_termination = let premature_nil_termination =
register_from_string ~id:"PREMATURE_NIL_TERMINATION_ARGUMENT" Biabduction register_from_string ~id:"PREMATURE_NIL_TERMINATION_ARGUMENT" Warning Biabduction
let pulse_memory_leak = register_from_string ~enabled:false ~id:"PULSE_MEMORY_LEAK" Pulse let pulse_memory_leak = register_from_string ~enabled:false ~id:"PULSE_MEMORY_LEAK" Error Pulse
let pure_function = register_from_string ~id:"PURE_FUNCTION" Purity let pure_function = register_from_string ~id:"PURE_FUNCTION" Error Purity
let quandary_taint_error = let quandary_taint_error =
register_from_string ~hum:"Taint Error" ~id:"QUANDARY_TAINT_ERROR" Quandary register_from_string ~hum:"Taint Error" ~id:"QUANDARY_TAINT_ERROR" Error Quandary
let resource_leak = register_from_string ~id:"RESOURCE_LEAK" Error Biabduction
let resource_leak = register_from_string ~id:"RESOURCE_LEAK" Biabduction let retain_cycle = register_from_string ~enabled:true ~id:"RETAIN_CYCLE" Error Biabduction
let retain_cycle = register_from_string ~enabled:true ~id:"RETAIN_CYCLE" Biabduction let skip_function =
register_from_string ~visibility:Developer ~enabled:false ~id:"SKIP_FUNCTION" Info Biabduction
let skip_function = register_from_string ~enabled:false ~id:"SKIP_FUNCTION" Biabduction
let skip_pointer_dereference = let skip_pointer_dereference =
register_from_string ~enabled:false ~id:"SKIP_POINTER_DEREFERENCE" Biabduction register_from_string ~enabled:false ~id:"SKIP_POINTER_DEREFERENCE" Info Biabduction
let shell_injection = register_from_string ~id:"SHELL_INJECTION" Quandary let shell_injection = register_from_string ~id:"SHELL_INJECTION" Error Quandary
let shell_injection_risk = register_from_string ~id:"SHELL_INJECTION_RISK" Quandary let shell_injection_risk = register_from_string ~id:"SHELL_INJECTION_RISK" Error Quandary
let sql_injection = register_from_string ~id:"SQL_INJECTION" Quandary let sql_injection = register_from_string ~id:"SQL_INJECTION" Error Quandary
let sql_injection_risk = register_from_string ~id:"SQL_INJECTION_RISK" Quandary let sql_injection_risk = register_from_string ~id:"SQL_INJECTION_RISK" Error Quandary
let stack_variable_address_escape = register_from_string ~id:"STACK_VARIABLE_ADDRESS_ESCAPE" Pulse let stack_variable_address_escape =
register_from_string ~id:"STACK_VARIABLE_ADDRESS_ESCAPE" Error Pulse
let starvation = register_from_string ~id:"STARVATION" ~hum:"UI Thread Starvation" Starvation
let starvation = register_from_string ~id:"STARVATION" ~hum:"UI Thread Starvation" Error Starvation
let static_initialization_order_fiasco = let static_initialization_order_fiasco =
register_from_string ~id:"STATIC_INITIALIZATION_ORDER_FIASCO" SIOF register_from_string ~id:"STATIC_INITIALIZATION_ORDER_FIASCO" Error SIOF
let strict_mode_violation = let strict_mode_violation =
register_from_string ~id:"STRICT_MODE_VIOLATION" ~hum:"Strict Mode Violation" Starvation register_from_string ~id:"STRICT_MODE_VIOLATION" ~hum:"Strict Mode Violation" Error Starvation
let strong_self_not_checked = let strong_self_not_checked =
register_from_string ~id:"STRONG_SELF_NOT_CHECKED" ~hum:"StrongSelf Not Checked" SelfInBlock register_from_string ~id:"STRONG_SELF_NOT_CHECKED" ~hum:"StrongSelf Not Checked" Error SelfInBlock
let symexec_memory_error = let symexec_memory_error =
register_from_string ~id:"Symexec_memory_error" ~hum:"Symbolic Execution Memory Error" Biabduction register_from_string ~visibility:Developer ~id:"Symexec_memory_error"
~hum:"Symbolic Execution Memory Error" Error Biabduction
let thread_safety_violation = register_from_string ~id:"THREAD_SAFETY_VIOLATION" RacerD let thread_safety_violation = register_from_string Warning ~id:"THREAD_SAFETY_VIOLATION" RacerD
let complexity_increase ~kind ~is_on_ui_thread = let complexity_increase ~kind ~is_on_ui_thread =
register_from_cost_string ~kind ~is_on_ui_thread "%s_COMPLEXITY_INCREASE" register_from_cost_string ~kind ~is_on_ui_thread "%s_COMPLEXITY_INCREASE"
let topl_error = register_from_string ~id:"TOPL_ERROR" TOPL let topl_error = register_from_string ~id:"TOPL_ERROR" Error TOPL
let unary_minus_applied_to_unsigned_expression = let unary_minus_applied_to_unsigned_expression =
register_from_string ~enabled:false ~id:"UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" Biabduction register_from_string ~enabled:false ~id:"UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" Warning
Biabduction
let uninitialized_value = register_from_string ~id:"UNINITIALIZED_VALUE" Uninit let uninitialized_value = register_from_string ~id:"UNINITIALIZED_VALUE" Error Uninit
let unreachable_code_after = register_from_string ~id:"UNREACHABLE_CODE" BufferOverrunChecker let unreachable_code_after = register_from_string ~id:"UNREACHABLE_CODE" Error BufferOverrunChecker
let use_after_delete = register_from_string ~id:"USE_AFTER_DELETE" Pulse let use_after_delete = register_from_string ~id:"USE_AFTER_DELETE" Error Pulse
let use_after_free = register_from_string ~id:"USE_AFTER_FREE" Pulse let use_after_free = register_from_string ~id:"USE_AFTER_FREE" Error Pulse
let use_after_lifetime = register_from_string ~id:"USE_AFTER_LIFETIME" Pulse let use_after_lifetime = register_from_string ~id:"USE_AFTER_LIFETIME" Error Pulse
let user_controlled_sql_risk = register_from_string ~id:"USER_CONTROLLED_SQL_RISK" Quandary let user_controlled_sql_risk = register_from_string ~id:"USER_CONTROLLED_SQL_RISK" Error Quandary
let untrusted_buffer_access = let untrusted_buffer_access =
register_from_string ~enabled:false ~id:"UNTRUSTED_BUFFER_ACCESS" Quandary register_from_string ~enabled:false ~id:"UNTRUSTED_BUFFER_ACCESS" Error Quandary
let untrusted_deserialization = register_from_string ~id:"UNTRUSTED_DESERIALIZATION" Quandary let untrusted_deserialization = register_from_string ~id:"UNTRUSTED_DESERIALIZATION" Error Quandary
let untrusted_deserialization_risk = let untrusted_deserialization_risk =
register_from_string ~id:"UNTRUSTED_DESERIALIZATION_RISK" Quandary register_from_string ~id:"UNTRUSTED_DESERIALIZATION_RISK" Error Quandary
let untrusted_environment_change_risk = let untrusted_environment_change_risk =
register_from_string ~id:"UNTRUSTED_ENVIRONMENT_CHANGE_RISK" Quandary register_from_string ~id:"UNTRUSTED_ENVIRONMENT_CHANGE_RISK" Error Quandary
let untrusted_file = register_from_string ~id:"UNTRUSTED_FILE" Quandary let untrusted_file = register_from_string ~id:"UNTRUSTED_FILE" Error Quandary
let untrusted_file_risk = register_from_string ~id:"UNTRUSTED_FILE_RISK" Quandary let untrusted_file_risk = register_from_string ~id:"UNTRUSTED_FILE_RISK" Error Quandary
let untrusted_heap_allocation = let untrusted_heap_allocation =
register_from_string ~enabled:false ~id:"UNTRUSTED_HEAP_ALLOCATION" Quandary register_from_string ~enabled:false ~id:"UNTRUSTED_HEAP_ALLOCATION" Error Quandary
let untrusted_intent_creation = register_from_string ~id:"UNTRUSTED_INTENT_CREATION" Quandary let untrusted_intent_creation = register_from_string ~id:"UNTRUSTED_INTENT_CREATION" Error Quandary
let untrusted_url_risk = register_from_string ~id:"UNTRUSTED_URL_RISK" Quandary let untrusted_url_risk = register_from_string ~id:"UNTRUSTED_URL_RISK" Error Quandary
let untrusted_variable_length_array = let untrusted_variable_length_array =
register_from_string ~id:"UNTRUSTED_VARIABLE_LENGTH_ARRAY" Quandary register_from_string ~id:"UNTRUSTED_VARIABLE_LENGTH_ARRAY" Error Quandary
let vector_invalidation = register_from_string ~id:"VECTOR_INVALIDATION" Pulse let vector_invalidation = register_from_string ~id:"VECTOR_INVALIDATION" Error Pulse
let weak_self_in_noescape_block = let weak_self_in_noescape_block =
register_from_string ~id:"WEAK_SELF_IN_NO_ESCAPE_BLOCK" SelfInBlock register_from_string ~id:"WEAK_SELF_IN_NO_ESCAPE_BLOCK" Error SelfInBlock
let wrong_argument_number = let wrong_argument_number =
register_from_string ~id:"Wrong_argument_number" ~hum:"Wrong Argument Number" Biabduction register_from_string ~visibility:Developer ~id:"Wrong_argument_number"
~hum:"Wrong Argument Number" Error Biabduction
let unreachable_cost_call ~kind = let unreachable_cost_call ~kind =

@ -7,9 +7,23 @@
open! IStd open! IStd
(** visibility of the issue type *)
type visibility =
| User (** always add to error log *)
| Developer (** only add to error log in some debug modes *)
| Silent (** never add to error log *)
[@@deriving compare, equal]
(** severity of the report *)
type severity = Like | Info | Advice | Warning | Error [@@deriving compare, equal, enumerate]
val string_of_severity : severity -> string
type t = private type t = private
{ unique_id: string { unique_id: string
; checker: Checker.t ; checker: Checker.t
; visibility: visibility
; mutable default_severity: severity
; mutable enabled: bool ; mutable enabled: bool
; mutable hum: string ; mutable hum: string
; mutable doc_url: string option ; mutable doc_url: string option
@ -33,6 +47,8 @@ val register_from_string :
-> ?doc_url:string -> ?doc_url:string
-> ?linters_def_file:string -> ?linters_def_file:string
-> id:string -> id:string
-> ?visibility:visibility
-> severity
-> Checker.t -> Checker.t
-> t -> t
(** Create a new issue and register it in the list of all issues. NOTE: if the issue with the same (** Create a new issue and register it in the list of all issues. NOTE: if the issue with the same
@ -42,7 +58,6 @@ val register_from_string :
updated when we encounter the definition of the issue type, eg in AL. *) updated when we encounter the definition of the issue type, eg in AL. *)
val checker_can_report : Checker.t -> t -> bool val checker_can_report : Checker.t -> t -> bool
[@@warning "-32"]
(** Whether the issue was registered as coming from the given checker. Important to call this before (** Whether the issue was registered as coming from the given checker. Important to call this before
reporting to keep documentation accurate. *) reporting to keep documentation accurate. *)

@ -1142,8 +1142,7 @@ let check_junk {InterproceduralAnalysis.proc_desc; err_log; tenv} prop =
let report_leak () = let report_leak () =
if not report_and_continue then raise exn if not report_and_continue then raise exn
else ( else (
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Error exn ;
Exceptions.Error exn ;
leaks_reported := alloc_attribute :: !leaks_reported ) leaks_reported := alloc_attribute :: !leaks_reported )
in in
if not ignore_leak then report_leak () ; if not ignore_leak then report_leak () ;

@ -31,5 +31,5 @@ let log_error_using_state proc_desc err_log exn =
match AnalysisState.get_loc () with Some l -> l | None -> Procdesc.Node.get_loc node' match AnalysisState.get_loc () with Some l -> l | None -> Procdesc.Node.get_loc node'
in in
let ltr = State.get_loc_trace () in let ltr = State.get_loc_trace () in
Reporting.log_issue_from_summary Exceptions.Error proc_desc err_log ~node ~session ~loc ~ltr Reporting.log_issue_from_summary Error proc_desc err_log ~node ~session ~loc ~ltr Biabduction
Biabduction exn exn

@ -13,7 +13,7 @@ val log_error_using_state : Procdesc.t -> Errlog.t -> exn -> unit
val log_issue_deprecated_using_state : val log_issue_deprecated_using_state :
Procdesc.t Procdesc.t
-> Errlog.t -> Errlog.t
-> Exceptions.severity -> IssueType.severity
-> ?node:Procdesc.Node.t -> ?node:Procdesc.Node.t
-> ?loc:Location.t -> ?loc:Location.t
-> ?ltr:Errlog.loc_trace -> ?ltr:Errlog.loc_trace

@ -2507,7 +2507,7 @@ let check_implication_base {InterproceduralAnalysis.proc_desc; err_log; tenv} ch
L.d_printfln "WARNING: footprint failed to find MISSING because: %s" s ; L.d_printfln "WARNING: footprint failed to find MISSING because: %s" s ;
None None
| Exceptions.Abduction_case_not_implemented _ as exn -> | Exceptions.Abduction_case_not_implemented _ as exn ->
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Error exn ; BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Error exn ;
None None

@ -55,7 +55,7 @@ let check_bad_index {InterproceduralAnalysis.proc_desc; err_log; tenv} pname p l
Exceptions.Array_out_of_bounds_l1 Exceptions.Array_out_of_bounds_l1
(Errdesc.explain_array_access pname tenv deref_str p loc, __POS__) (Errdesc.explain_array_access pname tenv deref_str p loc, __POS__)
in in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn
else if len_is_constant then else if len_is_constant then
let deref_str = Localise.deref_str_array_bound len_const_opt index_const_opt in let deref_str = Localise.deref_str_array_bound len_const_opt index_const_opt in
let desc = Errdesc.explain_array_access pname tenv deref_str p loc in let desc = Errdesc.explain_array_access pname tenv deref_str p loc in
@ -63,7 +63,7 @@ let check_bad_index {InterproceduralAnalysis.proc_desc; err_log; tenv} pname p l
if index_has_bounds () then Exceptions.Array_out_of_bounds_l2 (desc, __POS__) if index_has_bounds () then Exceptions.Array_out_of_bounds_l2 (desc, __POS__)
else Exceptions.Array_out_of_bounds_l3 (desc, __POS__) else Exceptions.Array_out_of_bounds_l3 (desc, __POS__)
in in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn
(** Perform bounds checking *) (** Perform bounds checking *)
@ -1014,8 +1014,7 @@ let check_type_size {InterproceduralAnalysis.proc_desc; err_log; tenv} pname pro
Exceptions.Pointer_size_mismatch Exceptions.Pointer_size_mismatch
(Errdesc.explain_dereference pname tenv deref_str prop loc, __POS__) (Errdesc.explain_dereference pname tenv deref_str prop loc, __POS__)
in in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn
exn
| None -> | None ->
L.d_str "texp: " ; L.d_str "texp: " ;
Exp.d_texp_full texp ; Exp.d_texp_full texp ;

@ -345,7 +345,7 @@ let check_inherently_dangerous_function {InterproceduralAnalysis.proc_desc; err_
Exceptions.Inherently_dangerous_function Exceptions.Inherently_dangerous_function
(Localise.desc_inherently_dangerous_function callee_pname) (Localise.desc_inherently_dangerous_function callee_pname)
in in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn
let reason_to_skip ~callee_desc : string option = let reason_to_skip ~callee_desc : string option =
@ -410,7 +410,7 @@ let check_arith_norm_exp {InterproceduralAnalysis.proc_desc; err_log; tenv} exp
(AnalysisState.get_loc_exn ()) (AnalysisState.get_loc_exn ())
in in
let exn = Exceptions.Divide_by_zero (desc, __POS__) in let exn = Exceptions.Divide_by_zero (desc, __POS__) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn ; BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn ;
(Prop.exp_normalize_prop tenv prop exp, prop') (Prop.exp_normalize_prop tenv prop exp, prop')
| Some (Attribute.UminusUnsigned (e, typ)), prop' -> | Some (Attribute.UminusUnsigned (e, typ)), prop' ->
let desc = let desc =
@ -418,7 +418,7 @@ let check_arith_norm_exp {InterproceduralAnalysis.proc_desc; err_log; tenv} exp
(AnalysisState.get_node_exn ()) (AnalysisState.get_loc_exn ()) (AnalysisState.get_node_exn ()) (AnalysisState.get_loc_exn ())
in in
let exn = Exceptions.Unary_minus_applied_to_unsigned_expression (desc, __POS__) in let exn = Exceptions.Unary_minus_applied_to_unsigned_expression (desc, __POS__) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn ; BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn ;
(Prop.exp_normalize_prop tenv prop exp, prop') (Prop.exp_normalize_prop tenv prop exp, prop')
| None, prop' -> | None, prop' ->
(Prop.exp_normalize_prop tenv prop exp, prop') (Prop.exp_normalize_prop tenv prop exp, prop')
@ -476,7 +476,7 @@ let check_already_dereferenced {InterproceduralAnalysis.proc_desc; err_log; tenv
(AnalysisState.get_node_exn ()) n (AnalysisState.get_loc_exn ()) (AnalysisState.get_node_exn ()) n (AnalysisState.get_loc_exn ())
in in
let exn = Exceptions.Null_test_after_dereference (desc, __POS__) in let exn = Exceptions.Null_test_after_dereference (desc, __POS__) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn
| None -> | None ->
() ()
@ -1206,8 +1206,7 @@ let rec sym_exec
ret_id_typ ret_typ actual_args = ret_id_typ ret_typ actual_args =
let skip_res () = let skip_res () =
let exn = Exceptions.Skip_function (Localise.desc_skip_function callee_pname) in let exn = Exceptions.Skip_function (Localise.desc_skip_function callee_pname) in
BiabductionReporting.log_issue_deprecated_using_state current_pdesc err_log Exceptions.Info BiabductionReporting.log_issue_deprecated_using_state current_pdesc err_log Info exn ;
exn ;
L.d_printfln "Skipping function '%a': %s" Procname.pp callee_pname reason ; L.d_printfln "Skipping function '%a': %s" Procname.pp callee_pname reason ;
unknown_or_scan_call ~is_scan:false ~reason ret_typ ret_annots unknown_or_scan_call ~is_scan:false ~reason ret_typ ret_annots
{ Builtin.instr { Builtin.instr
@ -1258,8 +1257,8 @@ let rec sym_exec
let exn = let exn =
Exceptions.Condition_always_true_false (desc, not (IntLit.iszero i), __POS__) Exceptions.Condition_always_true_false (desc, not (IntLit.iszero i), __POS__)
in in
BiabductionReporting.log_issue_deprecated_using_state current_pdesc err_log BiabductionReporting.log_issue_deprecated_using_state current_pdesc err_log Warning
Exceptions.Warning exn exn
| _ -> | _ ->
() ()
in in

@ -401,8 +401,7 @@ let check_path_errors_in_post {InterproceduralAnalysis.proc_desc= caller_pdesc;
in in
State.set_path new_path path_pos_opt ; State.set_path new_path path_pos_opt ;
let exn = Exceptions.Divide_by_zero (desc, __POS__) in let exn = Exceptions.Divide_by_zero (desc, __POS__) in
BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log Warning exn )
Exceptions.Warning exn )
| _ -> | _ ->
() ()
in in
@ -1133,8 +1132,7 @@ let exe_spec
missing_sigma_objc_class callee_summary ) ; missing_sigma_objc_class callee_summary ) ;
let log_check_exn check = let log_check_exn check =
let exn = get_check_exn tenv check callee_pname loc __POS__ in let exn = get_check_exn tenv check callee_pname loc __POS__ in
BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log Warning exn
Exceptions.Warning exn
in in
let do_split () = let do_split () =
process_splitting actual_pre sub1 sub2 frame missing_pi missing_sigma frame_fld missing_fld process_splitting actual_pre sub1 sub2 frame missing_pi missing_sigma frame_fld missing_fld

@ -404,7 +404,7 @@ let forward_tabulate ({InterproceduralAnalysis.proc_desc; err_log; tenv; _} as a
L.d_strln "SIL INSTR:" ; L.d_strln "SIL INSTR:" ;
Procdesc.Node.d_instrs ~highlight:(AnalysisState.get_instr ()) curr_node ; Procdesc.Node.d_instrs ~highlight:(AnalysisState.get_instr ()) curr_node ;
L.d_ln () ; L.d_ln () ;
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Error exn ; BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Error exn ;
State.mark_instr_fail exn State.mark_instr_fail exn
in in
let exe_iter f pathset = let exe_iter f pathset =
@ -493,7 +493,7 @@ let remove_locals_formals_and_check {InterproceduralAnalysis.proc_desc; err_log;
let dexp_opt, _ = Errdesc.vpath_find tenv p (Exp.Lvar pvar) in let dexp_opt, _ = Errdesc.vpath_find tenv p (Exp.Lvar pvar) in
let desc = Errdesc.explain_stack_variable_address_escape loc pvar dexp_opt in let desc = Errdesc.explain_stack_variable_address_escape loc pvar dexp_opt in
let exn = Exceptions.Stack_variable_address_escape (desc, __POS__) in let exn = Exceptions.Stack_variable_address_escape (desc, __POS__) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning exn BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning exn
in in
List.iter ~f:check_pvar pvars ; List.iter ~f:check_pvar pvars ;
p' p'
@ -803,7 +803,7 @@ let perform_analysis_phase ({InterproceduralAnalysis.proc_desc; err_log; tenv} a
in in
let get_results (wl : Worklist.t) () = let get_results (wl : Worklist.t) () =
State.process_execution_failures State.process_execution_failures
(BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Warning) ; (BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Warning) ;
let results = collect_analysis_result analysis_data wl proc_cfg in let results = collect_analysis_result analysis_data wl proc_cfg in
let specs = let specs =
try extract_specs analysis_data (ProcCfg.Exceptional.proc_desc proc_cfg) results try extract_specs analysis_data (ProcCfg.Exceptional.proc_desc proc_cfg) results
@ -812,8 +812,7 @@ let perform_analysis_phase ({InterproceduralAnalysis.proc_desc; err_log; tenv} a
Exceptions.Internal_error Exceptions.Internal_error
(Localise.verbatim_desc "Leak_while_collecting_specs_after_footprint") (Localise.verbatim_desc "Leak_while_collecting_specs_after_footprint")
in in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Error BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Error exn ;
exn ;
(* returning no specs *) [] (* returning no specs *) []
in in
(specs, BiabductionSummary.FOOTPRINT) (specs, BiabductionSummary.FOOTPRINT)
@ -928,8 +927,8 @@ let report_custom_errors {InterproceduralAnalysis.proc_desc; err_log; tenv} summ
if all_post_error || is_unavoidable tenv pre then if all_post_error || is_unavoidable tenv pre then
let loc = Procdesc.get_loc proc_desc in let loc = Procdesc.get_loc proc_desc in
let err_desc = Localise.desc_custom_error loc in let err_desc = Localise.desc_custom_error loc in
let exn = Exceptions.Custom_error (custom_error, err_desc) in let exn = Exceptions.Custom_error (custom_error, Error, err_desc) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Error exn BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Error exn
in in
List.iter ~f:report error_preconditions List.iter ~f:report error_preconditions

@ -331,7 +331,7 @@ module CxxAnnotationSpecs = struct
(List.Assoc.find ~equal:String.equal spec_cfg "doc_url") (List.Assoc.find ~equal:String.equal spec_cfg "doc_url")
in in
let linters_def_file = Option.value_map ~default:"" ~f:Fn.id Config.inferconfig_file in let linters_def_file = Option.value_map ~default:"" ~f:Fn.id Config.inferconfig_file in
IssueType.register_from_string ~id:spec_name ~doc_url ~linters_def_file IssueType.register_from_string ~id:spec_name ~doc_url ~linters_def_file Error
AnnotationReachability AnnotationReachability
in in
Reporting.log_error proc_desc err_log ~loc ~ltr:final_trace AnnotationReachability issue_type Reporting.log_error proc_desc err_log ~loc ~ltr:final_trace AnnotationReachability issue_type

@ -640,8 +640,8 @@ let make_trace ~report_kind original_exp =
let log_issue current_pname ~issue_log ~loc ~ltr ~access issue_type error_message = let log_issue current_pname ~issue_log ~loc ~ltr ~access issue_type error_message =
Reporting.log_issue_external current_pname Exceptions.Warning ~issue_log ~loc ~ltr ~access Reporting.log_issue_external current_pname Warning ~issue_log ~loc ~ltr ~access issue_type
issue_type error_message error_message
type reported_access = type reported_access =

@ -470,8 +470,7 @@ end = struct
let issue_log_of loc_map = let issue_log_of loc_map =
let log_report ~issue_log loc {problem; pname; ltr; message} = let log_report ~issue_log loc {problem; pname; ltr; message} =
let issue_type = issue_type_of_problem problem in let issue_type = issue_type_of_problem problem in
Reporting.log_issue_external ~issue_log pname Exceptions.Error ~loc ~ltr Starvation issue_type Reporting.log_issue_external ~issue_log pname Error ~loc ~ltr Starvation issue_type message
message
in in
let mk_deduped_report ({message} as report) = let mk_deduped_report ({message} as report) =
{ report with { report with

@ -275,11 +275,11 @@ let issue_of_cost kind CostIssues.{complexity_increase_issue; unreachable_issue;
in in
("", curr_cost_trace) :: polynomial_traces |> Errlog.concat_traces ("", curr_cost_trace) :: polynomial_traces |> Errlog.concat_traces
in in
let severity = Exceptions.Advice in let severity = IssueType.Advice in
Some Some
{ Jsonbug_j.bug_type= issue_type.IssueType.unique_id { Jsonbug_j.bug_type= issue_type.IssueType.unique_id
; qualifier ; qualifier
; severity= Exceptions.severity_string severity ; severity= IssueType.string_of_severity severity
; line ; line
; column ; column
; procedure= cost_info.Jsonbug_t.procedure_id ; procedure= cost_info.Jsonbug_t.procedure_id

@ -45,7 +45,7 @@ let compute_hash ~(severity : string) ~(bug_type : string) ~(proc_name : Procnam
let loc_trace_to_jsonbug_record trace_list ekind = let loc_trace_to_jsonbug_record trace_list ekind =
match ekind with match ekind with
| Exceptions.Info -> | IssueType.Info ->
[] []
| _ -> | _ ->
let trace_item_to_record trace_item = let trace_item_to_record trace_item =
@ -168,7 +168,7 @@ module JsonIssuePrinter = MakeJsonListPrinter (struct
&& should_report_source_file && should_report_source_file
&& should_report err_key.issue_type err_key.err_desc && should_report err_key.issue_type err_key.err_desc
then then
let severity = Exceptions.severity_string err_key.severity in let severity = IssueType.string_of_severity err_key.severity in
let bug_type = err_key.issue_type.unique_id in let bug_type = err_key.issue_type.unique_id in
let file = let file =
SourceFile.to_string ~force_relative:Config.report_force_relative_path source_file SourceFile.to_string ~force_relative:Config.report_force_relative_path source_file
@ -257,10 +257,8 @@ module JsonCostsPrinter = MakeJsonListPrinter (struct
; degree= ; degree=
Option.map (CostDomain.BasicCost.degree cost) ~f:Polynomials.Degree.encode_to_int Option.map (CostDomain.BasicCost.degree cost) ~f:Polynomials.Degree.encode_to_int
; hum= hum cost ; hum= hum cost
; trace= ; trace= loc_trace_to_jsonbug_record (CostDomain.BasicCost.polynomial_traces cost) Advice
loc_trace_to_jsonbug_record }
(CostDomain.BasicCost.polynomial_traces cost)
Exceptions.Advice }
in in
let cost_item = let cost_item =
let file = let file =

@ -10,7 +10,7 @@ open! IStd
val potential_exception_message : string val potential_exception_message : string
val loc_trace_to_jsonbug_record : val loc_trace_to_jsonbug_record :
Errlog.loc_trace_elem list -> Exceptions.severity -> Jsonbug_t.json_trace_item list Errlog.loc_trace_elem list -> IssueType.severity -> Jsonbug_t.json_trace_item list
val censored_reason : IssueType.t -> SourceFile.t -> string option val censored_reason : IssueType.t -> SourceFile.t -> string option

@ -37,7 +37,7 @@ module ReportableViolation : sig
; param_position: int ; param_position: int
; function_procname: Procname.t } ; function_procname: Procname.t }
val get_severity : t -> Exceptions.severity val get_severity : t -> IssueType.severity
(** Severity of the violation to be reported *) (** Severity of the violation to be reported *)
val get_description : val get_description :

@ -47,7 +47,7 @@ let get_reportable_typing_rules_violations_for_mode ~nullsafe_mode issues =
type meta_issue = type meta_issue =
{ issue_type: IssueType.t { issue_type: IssueType.t
; description: string ; description: string
; severity: Exceptions.severity ; severity: IssueType.severity
; meta_issue_info: Jsonbug_t.nullsafe_meta_issue_info } ; meta_issue_info: Jsonbug_t.nullsafe_meta_issue_info }
let mode_to_json mode = let mode_to_json mode =
@ -119,7 +119,7 @@ let make_meta_issue modes_and_issues top_level_class_mode top_level_class_name =
`@Nullsafe(Nullsafe.Mode.LOCAL)` to prevent regressions." `@Nullsafe(Nullsafe.Mode.LOCAL)` to prevent regressions."
(JavaClassName.classname top_level_class_name) (JavaClassName.classname top_level_class_name)
in in
(IssueType.eradicate_meta_class_can_be_nullsafe, message, Exceptions.Advice) (IssueType.eradicate_meta_class_can_be_nullsafe, message, IssueType.Advice)
| None -> | None ->
(* This class can not be made @Nullsafe without extra work *) (* This class can not be made @Nullsafe without extra work *)
let issue_count_to_make_nullsafe = let issue_count_to_make_nullsafe =
@ -131,7 +131,7 @@ let make_meta_issue modes_and_issues top_level_class_mode top_level_class_name =
, Format.asprintf "`%s` needs %d issues to be fixed in order to be marked @Nullsafe." , Format.asprintf "`%s` needs %d issues to be fixed in order to be marked @Nullsafe."
(JavaClassName.classname top_level_class_name) (JavaClassName.classname top_level_class_name)
issue_count_to_make_nullsafe issue_count_to_make_nullsafe
, Exceptions.Info ) , IssueType.Info )
else if currently_reportable_issue_count > 0 then else if currently_reportable_issue_count > 0 then
(* This class is @Nullsafe, but broken. This should not happen often if there is enforcement for (* This class is @Nullsafe, but broken. This should not happen often if there is enforcement for
@Nullsafe mode error in the target codebase. *) @Nullsafe mode error in the target codebase. *)
@ -140,12 +140,12 @@ let make_meta_issue modes_and_issues top_level_class_mode top_level_class_name =
"@Nullsafe classes should have exactly zero nullability issues. `%s` has %d." "@Nullsafe classes should have exactly zero nullability issues. `%s` has %d."
(JavaClassName.classname top_level_class_name) (JavaClassName.classname top_level_class_name)
currently_reportable_issue_count currently_reportable_issue_count
, Exceptions.Info ) , IssueType.Info )
else else
( IssueType.eradicate_meta_class_is_nullsafe ( IssueType.eradicate_meta_class_is_nullsafe
, Format.asprintf "Class %a is free of nullability issues." JavaClassName.pp , Format.asprintf "Class %a is free of nullability issues." JavaClassName.pp
top_level_class_name top_level_class_name
, Exceptions.Info ) , IssueType.Info )
in in
{issue_type; description; severity; meta_issue_info} {issue_type; description; severity; meta_issue_info}
@ -218,7 +218,7 @@ let analyze_nullsafe_annotations tenv source_file class_name class_struct issue_
annotation can be removed." annotation can be removed."
(JavaClassName.classname class_name) (JavaClassName.classname class_name)
in in
log_issue ~issue_log ~loc ~nullsafe_extra ~severity:Exceptions.Advice log_issue ~issue_log ~loc ~nullsafe_extra ~severity:Advice
IssueType.eradicate_redundant_nested_class_annotation description IssueType.eradicate_redundant_nested_class_annotation description
| Error (NullsafeMode.NestedModeIsWeaker (ExtraTrustClass wrongly_trusted_classes)) -> | Error (NullsafeMode.NestedModeIsWeaker (ExtraTrustClass wrongly_trusted_classes)) ->
(* The list can not be empty *) (* The list can not be empty *)
@ -229,7 +229,7 @@ let analyze_nullsafe_annotations tenv source_file class_name class_struct issue_
trust list. Remove `%s` from trust list." trust list. Remove `%s` from trust list."
(JavaClassName.classname example_of_wrongly_trusted_class) (JavaClassName.classname example_of_wrongly_trusted_class)
in in
log_issue ~issue_log ~loc ~nullsafe_extra ~severity:Exceptions.Warning log_issue ~issue_log ~loc ~nullsafe_extra ~severity:Warning
IssueType.eradicate_bad_nested_class_annotation description IssueType.eradicate_bad_nested_class_annotation description
| Error (NullsafeMode.NestedModeIsWeaker Other) -> | Error (NullsafeMode.NestedModeIsWeaker Other) ->
let description = let description =
@ -238,7 +238,7 @@ let analyze_nullsafe_annotations tenv source_file class_name class_struct issue_
class. This annotation will be ignored." class. This annotation will be ignored."
(JavaClassName.classname class_name) (JavaClassName.classname class_name)
in in
log_issue ~issue_log ~loc ~nullsafe_extra ~severity:Exceptions.Warning log_issue ~issue_log ~loc ~nullsafe_extra ~severity:Warning
IssueType.eradicate_bad_nested_class_annotation description IssueType.eradicate_bad_nested_class_annotation description

@ -31,7 +31,7 @@ module ReportableViolation : sig
(** Depending on the mode, violation might or might not be important enough to be reported to the (** Depending on the mode, violation might or might not be important enough to be reported to the
user. If it should NOT be reported for that mode, this function will return None. *) user. If it should NOT be reported for that mode, this function will return None. *)
val get_severity : t -> Exceptions.severity val get_severity : t -> IssueType.severity
(** Severity of the violation to be reported *) (** Severity of the violation to be reported *)
val get_description : val get_description :

@ -13,6 +13,6 @@ val report_error :
-> IssueType.t -> IssueType.t
-> Location.t -> Location.t
-> ?field_name:Fieldname.t option -> ?field_name:Fieldname.t option
-> severity:Exceptions.severity -> severity:IssueType.severity
-> string -> string
-> unit -> unit

@ -38,7 +38,7 @@ module ReportableViolation : sig
(** Depending on the mode, violation might or might not be important enough to be reported to the (** Depending on the mode, violation might or might not be important enough to be reported to the
user. If it should NOT be reported for that mode, this function will return None. *) user. If it should NOT be reported for that mode, this function will return None. *)
val get_severity : t -> Exceptions.severity val get_severity : t -> IssueType.severity
(** Severity of the violation to be reported *) (** Severity of the violation to be reported *)
val get_description : val get_description :

@ -247,7 +247,7 @@ let severity = function
(* Explicit @Nullsafe modes suppose that enforcement is made on CI side to not allow violations in the codebase. (* Explicit @Nullsafe modes suppose that enforcement is made on CI side to not allow violations in the codebase.
Hence it should be an error. Hence it should be an error.
*) *)
Exceptions.Error IssueType.Error
| Default -> | Default ->
(* Enforcement is not supposed to be setup in default modes. *) (* Enforcement is not supposed to be setup in default modes. *)
Exceptions.Warning IssueType.Warning

@ -45,7 +45,7 @@ val is_in_trust_list : t -> JavaClassName.t -> bool
val is_stricter_than : stricter:t -> weaker:t -> bool val is_stricter_than : stricter:t -> weaker:t -> bool
(** Check whether [stricter] is (strongly) stricter than [weaker] *) (** Check whether [stricter] is (strongly) stricter than [weaker] *)
val severity : t -> Exceptions.severity val severity : t -> IssueType.severity
(** Provides a default choice of issue severity for a particular mode. Rule is: severity should be (** Provides a default choice of issue severity for a particular mode. Rule is: severity should be
ERROR if and only if it is enforced. *) ERROR if and only if it is enforced. *)

@ -233,7 +233,7 @@ let get_error_info_if_reportable_lazy ~nullsafe_mode err_instance =
Until it is made non-precise, it is recommended to not turn this warning on. Until it is made non-precise, it is recommended to not turn this warning on.
But even when it is on, this should not be more than advice. But even when it is on, this should not be more than advice.
*) *)
Exceptions.Advice ) ) IssueType.Advice ) )
| Over_annotation {over_annotated_violation; violation_type} -> | Over_annotation {over_annotated_violation; violation_type} ->
Some Some
( lazy ( lazy
@ -245,7 +245,7 @@ let get_error_info_if_reportable_lazy ~nullsafe_mode err_instance =
IssueType.eradicate_return_over_annotated ) IssueType.eradicate_return_over_annotated )
, None , None
, (* Very non-precise issue. Should be actually turned off unless for experimental purposes. *) , (* Very non-precise issue. Should be actually turned off unless for experimental purposes. *)
Exceptions.Advice ) ) IssueType.Advice ) )
| Field_not_initialized {field_name} -> | Field_not_initialized {field_name} ->
Some Some
( lazy ( lazy

@ -9,10 +9,10 @@ open! IStd
open OUnit2 open OUnit2
let order_tests _ = let order_tests _ =
assert_equal (-1) (Exceptions.compare_severity Exceptions.Like Exceptions.Info) ; assert_equal (-1) (IssueType.compare_severity Like Info) ;
assert_equal (-1) (Exceptions.compare_severity Exceptions.Info Exceptions.Advice) ; assert_equal (-1) (IssueType.compare_severity Info Advice) ;
assert_equal (-1) (Exceptions.compare_severity Exceptions.Advice Exceptions.Warning) ; assert_equal (-1) (IssueType.compare_severity Advice Warning) ;
assert_equal (-1) (Exceptions.compare_severity Exceptions.Warning Exceptions.Error) assert_equal (-1) (IssueType.compare_severity Warning Error)
let tests = "severity_test_suite" >::: ["severity_order_tests" >:: order_tests] let tests = "severity_test_suite" >::: ["severity_order_tests" >:: order_tests]

Loading…
Cancel
Save