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}
| BackendNode of {node: Procdesc.Node.t}
type err_key =
{severity: Exceptions.severity; issue_type: IssueType.t; err_desc: Localise.error_desc}
type err_key = {severity: IssueType.severity; issue_type: IssueType.t; err_desc: Localise.error_desc}
[@@deriving compare]
(** Data associated to a specific error *)
@ -84,7 +83,7 @@ type err_data =
; loc: Location.t
; loc_in_ml_source: L.ocaml_pos option
; loc_trace: loc_trace
; visibility: Exceptions.visibility
; visibility: IssueType.visibility
; linters_def_file: string option
; doc_url: 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 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)
&& Localise.error_desc_equal key1.err_desc key2.err_desc
end
@ -143,7 +142,7 @@ let fold (f : err_key -> err_data -> 'a -> 'a) t acc =
(** Print errors from error log *)
let pp_errors fmt (errlog : t) =
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
in
ErrLogHash.iter f errlog
@ -152,7 +151,7 @@ let pp_errors fmt (errlog : t) =
(** Print warnings from error log *)
let pp_warnings fmt (errlog : t) =
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
in
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
in
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
pp_eds err_datas
in
let pp severity =
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
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 +
@ -223,9 +222,8 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
false
in
let should_report =
Exceptions.equal_visibility error.visibility Exceptions.Exn_user
|| Config.developer_mode
&& Exceptions.equal_visibility error.visibility Exceptions.Exn_developer
IssueType.equal_visibility error.issue_type.visibility User
|| (Config.developer_mode && IssueType.equal_visibility error.issue_type.visibility Developer)
in
if should_report && (not hide_java_loc_zero) && not hide_memory_error then
let added =
@ -245,7 +243,7 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
; loc
; loc_in_ml_source= error.ocaml_pos
; loc_trace= ltr
; visibility= error.visibility
; visibility= error.issue_type.visibility
; linters_def_file
; doc_url
; access
@ -260,7 +258,7 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u
"@\n%a@\n@?"
(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 pp fmt =
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
in
let d =
match severity with
| Exceptions.Error ->
match (severity : IssueType.severity) with
| Error ->
L.d_error
| Exceptions.Warning ->
| Warning ->
L.d_warning
| Exceptions.Info | Exceptions.Advice | Exceptions.Like ->
| Info | Advice | Like ->
L.d_info
in
d warn_str ;

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

@ -10,20 +10,6 @@ open! IStd
module L = Logging
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 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 Custom_error of string * Localise.error_desc
exception Custom_error of string * IssueType.severity * Localise.error_desc
exception
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
; description: Localise.error_desc
; ocaml_pos: L.ocaml_pos option (** location in the infer source code *)
; visibility: visibility
; severity: severity option }
; severity: IssueType.severity option }
let recognize_exception exn =
match exn with
@ -124,182 +109,145 @@ let recognize_exception exn =
{ issue_type= IssueType.abduction_case_not_implemented
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Analysis_stops (desc, ocaml_pos_opt) ->
{ issue_type= IssueType.biabduction_analysis_stops
; description= desc
; ocaml_pos= ocaml_pos_opt
; visibility= Exn_developer
; severity= None }
| Array_of_pointsto ocaml_pos ->
{ issue_type= IssueType.array_of_pointsto
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Array_out_of_bounds_l1 (desc, ocaml_pos) ->
{ issue_type= IssueType.array_out_of_bounds_l1
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= Some Error }
| Array_out_of_bounds_l2 (desc, ocaml_pos) ->
{ issue_type= IssueType.array_out_of_bounds_l2
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Array_out_of_bounds_l3 (desc, ocaml_pos) ->
{ issue_type= IssueType.array_out_of_bounds_l3
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Assert_failure (f, l, c) ->
let ocaml_pos = (f, l, c, c) in
{ issue_type= IssueType.assert_failure
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Bad_footprint ocaml_pos ->
{ issue_type= IssueType.bad_footprint
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Biabd_use_after_free (desc, ocaml_pos) ->
{ issue_type= IssueType.biabd_use_after_free
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Cannot_star ocaml_pos ->
{ issue_type= IssueType.cannot_star
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Class_cast_exception (desc, ocaml_pos) ->
{ issue_type= IssueType.class_cast_exception
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Condition_always_true_false (desc, b, ocaml_pos) ->
let issue_type =
if b then IssueType.biabd_condition_always_true else IssueType.biabd_condition_always_false
in
{ issue_type
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Custom_error (error_msg, desc) ->
{ issue_type= IssueType.register_from_string ~id:error_msg Biabduction
{issue_type; description= desc; ocaml_pos= Some ocaml_pos; severity= None}
| Custom_error (error_msg, severity, desc) ->
{ issue_type= IssueType.register_from_string ~id:error_msg severity Biabduction
; description= desc
; ocaml_pos= None
; visibility= Exn_user
; severity= None }
| Dangling_pointer_dereference (user_visible, desc, ocaml_pos) ->
let issue_type, visibility =
if user_visible then (IssueType.dangling_pointer_dereference, Exn_user)
else (IssueType.dangling_pointer_dereference_maybe, Exn_developer)
let issue_type =
if user_visible then IssueType.dangling_pointer_dereference
else IssueType.dangling_pointer_dereference_maybe
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 ->
{ issue_type= IssueType.deallocate_stack_variable
; description= desc
; ocaml_pos= None
; visibility= Exn_user
; severity= None }
| Deallocate_static_memory desc ->
{ issue_type= IssueType.deallocate_static_memory
; description= desc
; ocaml_pos= None
; visibility= Exn_user
; severity= None }
| Deallocation_mismatch (desc, ocaml_pos) ->
{ issue_type= IssueType.deallocation_mismatch
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Divide_by_zero (desc, ocaml_pos) ->
{ issue_type= IssueType.divide_by_zero
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error }
| Empty_vector_access (desc, ocaml_pos) ->
{ issue_type= IssueType.empty_vector_access
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error }
| Field_not_null_checked (desc, ocaml_pos) ->
{ issue_type= IssueType.field_not_null_checked
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Warning }
| Frontend_warning (issue_type, desc, ocaml_pos) ->
{ issue_type
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
{issue_type; description= desc; ocaml_pos= Some ocaml_pos; severity= None}
| 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) ->
{ issue_type= IssueType.null_dereference
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Null_test_after_dereference (desc, ocaml_pos) ->
{ issue_type= IssueType.null_test_after_dereference
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Pointer_size_mismatch (desc, ocaml_pos) ->
{ issue_type= IssueType.pointer_size_mismatch
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error }
| Inherently_dangerous_function desc ->
{ issue_type= IssueType.inherently_dangerous_function
; description= desc
; ocaml_pos= None
; visibility= Exn_developer
; severity= None }
| Internal_error desc ->
{ issue_type= IssueType.internal_error
; description= desc
; ocaml_pos= None
; visibility= Exn_developer
; severity= None }
{issue_type= IssueType.internal_error; description= desc; ocaml_pos= None; severity= None}
| Leak (fp_part, (user_visible, error_desc), done_array_abstraction, resource, ocaml_pos) ->
if done_array_abstraction then
{ issue_type= IssueType.leak_after_array_abstraction
; description= error_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
else if fp_part then
{ issue_type= IssueType.leak_in_footprint
; description= error_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
else if not user_visible then
{ issue_type= IssueType.leak_unknown_origin
; description= error_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
else
let issue_type =
@ -313,104 +261,82 @@ let recognize_exception exn =
| PredSymb.Rignore ->
IssueType.memory_leak
in
{ issue_type
; description= error_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
{issue_type; description= error_desc; ocaml_pos= Some ocaml_pos; severity= None}
| Missing_fld (fld, ocaml_pos) ->
let desc = Localise.verbatim_desc (Fieldname.to_full_string fld) in
{ issue_type= IssueType.missing_fld
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Premature_nil_termination (desc, ocaml_pos) ->
{ issue_type= IssueType.premature_nil_termination
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Parameter_not_null_checked (desc, ocaml_pos) ->
{ issue_type= IssueType.parameter_not_null_checked
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Warning }
| Precondition_not_found (desc, ocaml_pos) ->
{ issue_type= IssueType.precondition_not_found
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Precondition_not_met (desc, ocaml_pos) ->
{ issue_type= IssueType.precondition_not_met
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= Some Warning }
(* always a warning *)
| Retain_cycle (desc, ocaml_pos) ->
{ issue_type= IssueType.retain_cycle
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Registered_observer_being_deallocated (desc, ocaml_pos) ->
{ issue_type= IssueType.biabd_registered_observer_being_deallocated
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error }
| Stack_variable_address_escape (desc, ocaml_pos) ->
{ issue_type= IssueType.biabd_stack_variable_address_escape
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Error }
| SymOp.Analysis_failure_exe _ ->
{ issue_type= IssueType.failure_exe
; description= Localise.no_desc
; ocaml_pos= None
; visibility= Exn_system
; severity= None }
| Skip_function desc ->
{ issue_type= IssueType.skip_function
; description= desc
; ocaml_pos= None
; visibility= Exn_developer
; severity= None }
{issue_type= IssueType.skip_function; description= desc; ocaml_pos= None; severity= None}
| Skip_pointer_dereference (desc, ocaml_pos) ->
{ issue_type= IssueType.skip_pointer_dereference
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= Some Info }
(* always an info *)
| Symexec_memory_error ocaml_pos ->
{ issue_type= IssueType.symexec_memory_error
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| Unary_minus_applied_to_unsigned_expression (desc, ocaml_pos) ->
{ issue_type= IssueType.unary_minus_applied_to_unsigned_expression
; description= desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_user
; severity= None }
| Wrong_argument_number ocaml_pos ->
{ issue_type= IssueType.wrong_argument_number
; description= Localise.no_desc
; ocaml_pos= Some ocaml_pos
; visibility= Exn_developer
; severity= None }
| exn ->
{ issue_type= IssueType.failure_exe
; description=
Localise.verbatim_desc (F.asprintf "%a: %s" Exn.pp exn (Caml.Printexc.get_backtrace ()))
; ocaml_pos= None
; visibility= Exn_system
; severity= None }
@ -428,23 +354,12 @@ let print_exception_html s exn =
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 *)
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
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 *)
let handle_exception exn =
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 *)
(** 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 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 Custom_error of string * Localise.error_desc
exception Custom_error of string * IssueType.severity * Localise.error_desc
exception
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
val severity_string : severity -> string
(** string describing an error kind *)
val handle_exception : exn -> bool
(** 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 :
Location.t
-> severity
-> IssueType.severity
-> IssueType.t
-> Localise.error_desc
-> Logging.ocaml_pos option
@ -136,7 +119,6 @@ type t =
{ issue_type: IssueType.t
; description: Localise.error_desc
; ocaml_pos: Logging.ocaml_pos option (** location in the infer source code *)
; visibility: visibility
; severity: severity option }
; severity: IssueType.severity option }
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 =
log_issue_from_summary_simplified Exceptions.Error attrs err_log ~loc ?ltr ?extras checker
issue_type error_message
log_issue_from_summary_simplified Error 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
issue_type error_message
log_issue_from_summary_simplified Warning attrs err_log ~loc ?ltr ?extras checker issue_type
error_message
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
val log_issue_from_summary :
Exceptions.severity
IssueType.severity
-> Procdesc.t
-> Errlog.t
-> node:Errlog.node
@ -26,7 +26,7 @@ val log_issue_from_summary :
-> unit
val log_frontend_issue :
Exceptions.severity
IssueType.severity
-> Errlog.t
-> loc:Location.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 :
Procname.t
-> issue_log:IssueLog.t
-> Exceptions.severity
-> IssueType.severity
-> loc:Location.t
-> ltr:Errlog.loc_trace
-> ?access:string

@ -177,15 +177,15 @@ let remove_new_lines_and_whitespace message =
let string_to_severity = function
| "WARNING" ->
Exceptions.Warning
IssueType.Warning
| "ERROR" ->
Exceptions.Error
IssueType.Error
| "INFO" ->
Exceptions.Info
IssueType.Info
| "ADVICE" ->
Exceptions.Advice
IssueType.Advice
| "LIKE" ->
Exceptions.Like
IssueType.Like
| s ->
L.die InternalError "Severity %s does not exist" s
@ -209,7 +209,7 @@ type issue_in_construction =
; description: string
; mode: CIssue.mode
; loc: Location.t
; severity: Exceptions.severity
; severity: IssueType.severity
; suggestion: string option }
(** 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
in
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
let issue_desc =
{ CIssue.issue_type

@ -149,8 +149,8 @@ let mutable_local_vars_advice context an =
else
Some
{ CIssue.issue_type= IssueType.mutable_local_variable_in_component_file
; severity= Exceptions.Advice
; mode= CIssue.On
; severity= Advice
; mode= On
; description=
"Local variable "
^ 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
Some
{ CIssue.issue_type= IssueType.component_factory_function
; severity= Exceptions.Advice
; mode= CIssue.Off
; severity= Advice
; mode= Off
; description= "Break out composite components"
; suggestion=
Some
@ -236,8 +236,8 @@ let component_with_unconventional_superclass_advice context an =
if condition then
Some
{ CIssue.issue_type= IssueType.component_with_unconventional_superclass
; severity= Exceptions.Advice
; mode= CIssue.On
; severity= Advice
; mode= On
; description= "Never Subclass Components"
; suggestion= Some "Instead, create a new subclass of CKCompositeComponent."
; loc= ALUtils.location_from_decl context if_decl }
@ -290,8 +290,8 @@ let component_with_multiple_factory_methods_advice context an =
List.map
~f:(fun meth_decl ->
{ CIssue.issue_type= IssueType.component_with_multiple_factory_methods
; severity= Exceptions.Advice
; mode= CIssue.On
; severity= Advice
; mode= On
; description= "Avoid Overrides"
; suggestion=
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
{ CIssue.issue_type= IssueType.component_initializer_with_side_effects
; severity= Exceptions.Advice
; mode= CIssue.On
; severity= Advice
; mode= On
; description= "No Side-effects"
; suggestion=
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
~f:(fun i ->
{ CIssue.issue_type= IssueType.component_file_line_count
; severity= Exceptions.Info
; mode= CIssue.Off
; severity= Info
; mode= Off
; description= "Line count analytics"
; suggestion= None
; 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
{ CIssue.issue_type= IssueType.component_file_cyclomatic_complexity
; severity= Exceptions.Info
; mode= CIssue.Off
; severity= Info
; mode= Off
; description= "Cyclomatic Complexity Incremental Marker"
; suggestion= None
; loc }

@ -24,13 +24,13 @@ type t =
; description: string (** Description in the error message *)
; mode: mode
; loc: Location.t (** location in the code *)
; severity: Exceptions.severity
; severity: IssueType.severity
; suggestion: string option (** an optional suggestion or correction *) }
let pp fmt issue =
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 " 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 " Description = %s@\n" issue.description ;
Format.fprintf fmt " Suggestion = %s@\n" (Option.value ~default:"" issue.suggestion) ;

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

@ -1185,7 +1185,7 @@ and () =
issue
| None ->
(* 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
IssueType.set_enabled issue b ;
issue_id )

@ -9,12 +9,33 @@ open! IStd
module F = Format
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
we want to keep track of the list of all the issues ever declared. *)
module Unsafe : sig
type t = private
{ unique_id: string
; checker: Checker.t
; visibility: visibility
; mutable default_severity: severity
; mutable enabled: bool
; mutable hum: string
; mutable doc_url: string option
@ -33,6 +54,8 @@ module Unsafe : sig
-> ?doc_url:string
-> ?linters_def_file:string
-> id:string
-> ?visibility:visibility
-> severity
-> Checker.t
-> t
@ -51,6 +74,8 @@ end = struct
type t =
{ unique_id: string
; checker: Checker.t
; visibility: visibility
; mutable default_severity: severity
; mutable enabled: bool
; mutable hum: string
; 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
of the issue type, eg in AL. *)
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
| ((Some
( { unique_id= _ (* we know it has to be the same *)
; checker= checker_old
; visibility= visibility_old
; default_severity= _ (* mutable field to update *)
; enabled= _ (* not touching this one since [Config] will have set it *)
; hum= _ (* mutable field to update *)
; doc_url= _ (* mutable field to update *)
; 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
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
"Checker definition for issue \"%s\" doesn't match: found new checker \"%s\" but \
checker \"%s\" was already registered for this issue type"
unique_id (Checker.get_name checker) (Checker.get_name checker_old) ;
"%s for issue \"%s\" doesn't match: found new %s \"%s\" but %s \"%s\" was already \
registered for this issue type"
(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) ;
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 ;
issue
| None ->
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 ;
issue
@ -126,7 +164,7 @@ end = struct
=
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
register_from_string ~enabled ~id:issue_type Cost
register_from_string ~enabled ~id:issue_type Error Cost
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 =
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 =
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 =
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 =
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 =
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 =
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 =
register_from_string ~enabled:false ~hum:"Condition Always True" ~id:"BIABD_CONDITION_ALWAYS_TRUE"
Biabduction
Warning Biabduction
let biabd_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 =
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 =
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 =
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 =
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 =
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 =
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 =
register_from_string ~id:"CHECKERS_ALLOCATES_MEMORY" ~hum:"Allocates Memory"
register_from_string ~id:"CHECKERS_ALLOCATES_MEMORY" ~hum:"Allocates Memory" Error
AnnotationReachability
let 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 =
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
let checkers_expensive_overrides_unexpensive =
register_from_string ~id:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED"
~hum:"Expensive Overrides Unannotated" AnnotationReachability
~hum:"Expensive Overrides Unannotated" Error AnnotationReachability
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
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 =
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 =
register_from_string ~id:"COMPONENT_FILE_CYCLOMATIC_COMPLEXITY" Linters
register_from_string ~id:"COMPONENT_FILE_CYCLOMATIC_COMPLEXITY" Info Linters
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 =
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 =
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 =
register_from_string ~id:"COMPONENT_WITH_UNCONVENTIONAL_SUPERCLASS" Linters
register_from_string ~id:"COMPONENT_WITH_UNCONVENTIONAL_SUPERCLASS" Advice Linters
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 =
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 =
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 =
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 =
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 =
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 *)
let _ =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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
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 =
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 =
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 =
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,
@ -391,7 +459,7 @@ let eradicate_meta_class_is_nullsafe =
register_from_string ~id:"ERADICATE_META_CLASS_IS_NULLSAFE"
~hum:
"Class is marked @Nullsafe and has 0 issues" (* Should be enabled for special integrations *)
~enabled:false Eradicate
~enabled:false Info Eradicate
(* Class is either:
@ -402,256 +470,287 @@ let eradicate_meta_class_needs_improvement =
register_from_string ~id:"ERADICATE_META_CLASS_NEEDS_IMPROVEMENT"
~hum:
"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 =
register_from_string ~id:"ERADICATE_META_CLASS_CAN_BE_NULLSAFE"
~hum:
"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 =
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 *)
let _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 =
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 =
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 =
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 =
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 =
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 =
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 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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
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 =
register_from_string ~id:"STATIC_INITIALIZATION_ORDER_FIASCO" SIOF
register_from_string ~id:"STATIC_INITIALIZATION_ORDER_FIASCO" Error SIOF
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 =
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 =
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 =
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 =
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 =
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 =
register_from_string ~id:"UNTRUSTED_DESERIALIZATION_RISK" Quandary
register_from_string ~id:"UNTRUSTED_DESERIALIZATION_RISK" Error Quandary
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 =
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 =
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 =
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 =
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 =

@ -7,9 +7,23 @@
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
{ unique_id: string
; checker: Checker.t
; visibility: visibility
; mutable default_severity: severity
; mutable enabled: bool
; mutable hum: string
; mutable doc_url: string option
@ -33,6 +47,8 @@ val register_from_string :
-> ?doc_url:string
-> ?linters_def_file:string
-> id:string
-> ?visibility:visibility
-> severity
-> Checker.t
-> t
(** 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. *)
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
reporting to keep documentation accurate. *)

@ -1142,8 +1142,7 @@ let check_junk {InterproceduralAnalysis.proc_desc; err_log; tenv} prop =
let report_leak () =
if not report_and_continue then raise exn
else (
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 ;
leaks_reported := alloc_attribute :: !leaks_reported )
in
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'
in
let ltr = State.get_loc_trace () in
Reporting.log_issue_from_summary Exceptions.Error proc_desc err_log ~node ~session ~loc ~ltr
Biabduction exn
Reporting.log_issue_from_summary Error proc_desc err_log ~node ~session ~loc ~ltr Biabduction
exn

@ -13,7 +13,7 @@ val log_error_using_state : Procdesc.t -> Errlog.t -> exn -> unit
val log_issue_deprecated_using_state :
Procdesc.t
-> Errlog.t
-> Exceptions.severity
-> IssueType.severity
-> ?node:Procdesc.Node.t
-> ?loc:Location.t
-> ?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 ;
None
| 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

@ -55,7 +55,7 @@ let check_bad_index {InterproceduralAnalysis.proc_desc; err_log; tenv} pname p l
Exceptions.Array_out_of_bounds_l1
(Errdesc.explain_array_access pname tenv deref_str p loc, __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
else if len_is_constant then
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
@ -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__)
else Exceptions.Array_out_of_bounds_l3 (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
(** Perform bounds checking *)
@ -1014,8 +1014,7 @@ let check_type_size {InterproceduralAnalysis.proc_desc; err_log; tenv} pname pro
Exceptions.Pointer_size_mismatch
(Errdesc.explain_dereference pname tenv deref_str prop loc, __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 ->
L.d_str "texp: " ;
Exp.d_texp_full texp ;

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

@ -401,8 +401,7 @@ let check_path_errors_in_post {InterproceduralAnalysis.proc_desc= caller_pdesc;
in
State.set_path new_path path_pos_opt ;
let exn = Exceptions.Divide_by_zero (desc, __POS__) in
BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log
Exceptions.Warning exn )
BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log Warning exn )
| _ ->
()
in
@ -1133,8 +1132,7 @@ let exe_spec
missing_sigma_objc_class callee_summary ) ;
let log_check_exn check =
let exn = get_check_exn tenv check callee_pname loc __POS__ in
BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log
Exceptions.Warning exn
BiabductionReporting.log_issue_deprecated_using_state caller_pdesc err_log Warning exn
in
let do_split () =
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:" ;
Procdesc.Node.d_instrs ~highlight:(AnalysisState.get_instr ()) curr_node ;
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
in
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 desc = Errdesc.explain_stack_variable_address_escape loc pvar dexp_opt 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
List.iter ~f:check_pvar pvars ;
p'
@ -803,7 +803,7 @@ let perform_analysis_phase ({InterproceduralAnalysis.proc_desc; err_log; tenv} a
in
let get_results (wl : Worklist.t) () =
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 specs =
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
(Localise.verbatim_desc "Leak_while_collecting_specs_after_footprint")
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 ;
(* returning no specs *) []
in
(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
let loc = Procdesc.get_loc proc_desc in
let err_desc = Localise.desc_custom_error loc in
let exn = Exceptions.Custom_error (custom_error, err_desc) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Exceptions.Error exn
let exn = Exceptions.Custom_error (custom_error, Error, err_desc) in
BiabductionReporting.log_issue_deprecated_using_state proc_desc err_log Error exn
in
List.iter ~f:report error_preconditions

@ -331,7 +331,7 @@ module CxxAnnotationSpecs = struct
(List.Assoc.find ~equal:String.equal spec_cfg "doc_url")
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
in
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 =
Reporting.log_issue_external current_pname Exceptions.Warning ~issue_log ~loc ~ltr ~access
issue_type error_message
Reporting.log_issue_external current_pname Warning ~issue_log ~loc ~ltr ~access issue_type
error_message
type reported_access =

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

@ -275,11 +275,11 @@ let issue_of_cost kind CostIssues.{complexity_increase_issue; unreachable_issue;
in
("", curr_cost_trace) :: polynomial_traces |> Errlog.concat_traces
in
let severity = Exceptions.Advice in
let severity = IssueType.Advice in
Some
{ Jsonbug_j.bug_type= issue_type.IssueType.unique_id
; qualifier
; severity= Exceptions.severity_string severity
; severity= IssueType.string_of_severity severity
; line
; column
; 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 =
match ekind with
| Exceptions.Info ->
| IssueType.Info ->
[]
| _ ->
let trace_item_to_record trace_item =
@ -168,7 +168,7 @@ module JsonIssuePrinter = MakeJsonListPrinter (struct
&& should_report_source_file
&& should_report err_key.issue_type err_key.err_desc
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 file =
SourceFile.to_string ~force_relative:Config.report_force_relative_path source_file
@ -257,10 +257,8 @@ module JsonCostsPrinter = MakeJsonListPrinter (struct
; degree=
Option.map (CostDomain.BasicCost.degree cost) ~f:Polynomials.Degree.encode_to_int
; hum= hum cost
; trace=
loc_trace_to_jsonbug_record
(CostDomain.BasicCost.polynomial_traces cost)
Exceptions.Advice }
; trace= loc_trace_to_jsonbug_record (CostDomain.BasicCost.polynomial_traces cost) Advice
}
in
let cost_item =
let file =

@ -10,7 +10,7 @@ open! IStd
val potential_exception_message : string
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

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

@ -47,7 +47,7 @@ let get_reportable_typing_rules_violations_for_mode ~nullsafe_mode issues =
type meta_issue =
{ issue_type: IssueType.t
; description: string
; severity: Exceptions.severity
; severity: IssueType.severity
; meta_issue_info: Jsonbug_t.nullsafe_meta_issue_info }
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."
(JavaClassName.classname top_level_class_name)
in
(IssueType.eradicate_meta_class_can_be_nullsafe, message, Exceptions.Advice)
(IssueType.eradicate_meta_class_can_be_nullsafe, message, IssueType.Advice)
| None ->
(* This class can not be made @Nullsafe without extra work *)
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."
(JavaClassName.classname top_level_class_name)
issue_count_to_make_nullsafe
, Exceptions.Info )
, IssueType.Info )
else if currently_reportable_issue_count > 0 then
(* This class is @Nullsafe, but broken. This should not happen often if there is enforcement for
@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."
(JavaClassName.classname top_level_class_name)
currently_reportable_issue_count
, Exceptions.Info )
, IssueType.Info )
else
( IssueType.eradicate_meta_class_is_nullsafe
, Format.asprintf "Class %a is free of nullability issues." JavaClassName.pp
top_level_class_name
, Exceptions.Info )
, IssueType.Info )
in
{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."
(JavaClassName.classname class_name)
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
| Error (NullsafeMode.NestedModeIsWeaker (ExtraTrustClass wrongly_trusted_classes)) ->
(* 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."
(JavaClassName.classname example_of_wrongly_trusted_class)
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
| Error (NullsafeMode.NestedModeIsWeaker Other) ->
let description =
@ -238,7 +238,7 @@ let analyze_nullsafe_annotations tenv source_file class_name class_struct issue_
class. This annotation will be ignored."
(JavaClassName.classname class_name)
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

@ -31,7 +31,7 @@ module ReportableViolation : sig
(** 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. *)
val get_severity : t -> Exceptions.severity
val get_severity : t -> IssueType.severity
(** Severity of the violation to be reported *)
val get_description :

@ -13,6 +13,6 @@ val report_error :
-> IssueType.t
-> Location.t
-> ?field_name:Fieldname.t option
-> severity:Exceptions.severity
-> severity:IssueType.severity
-> string
-> 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
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 *)
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.
Hence it should be an error.
*)
Exceptions.Error
IssueType.Error
| Default ->
(* 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
(** 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
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.
But even when it is on, this should not be more than advice.
*)
Exceptions.Advice ) )
IssueType.Advice ) )
| Over_annotation {over_annotated_violation; violation_type} ->
Some
( lazy
@ -245,7 +245,7 @@ let get_error_info_if_reportable_lazy ~nullsafe_mode err_instance =
IssueType.eradicate_return_over_annotated )
, None
, (* Very non-precise issue. Should be actually turned off unless for experimental purposes. *)
Exceptions.Advice ) )
IssueType.Advice ) )
| Field_not_initialized {field_name} ->
Some
( lazy

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

Loading…
Cancel
Save