From 69299ba6753f0c72207a3869940aad069885310f Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Tue, 15 Aug 2017 09:52:04 -0700 Subject: [PATCH] [filtering] improve issue type filtering CLI Summary: Instead of a whitelist and blacklist and default issue types and default blacklist and filtering, consider a simpler semantics where 1. checkers can be individually turned on or off on the command line 2. most checkers are on by default 3. `--no-filtering` turns all issue types on, but they can then be turned off again by further arguments This provides a more flexible CLI and is similar to other options in the infer CLI, where "global" behaviour is generally avoided. Dynamically created checkers (eg, AL linters) cause some complications in the implementation but I think the semantics is still clear. Also change the name of the option to mention "issue types" instead of "checks", since the latter can be confused with "checkers". Reviewed By: jberdine Differential Revision: D5583238 fbshipit-source-id: 21de476 --- infer/src/.merlin | 2 +- infer/src/IR/Errlog.ml | 16 +- infer/src/IR/Errlog.mli | 2 +- infer/src/IR/Exceptions.ml | 170 +++++------ infer/src/IR/Exceptions.mli | 5 +- infer/src/IR/Localise.ml | 185 ------------ infer/src/IR/Localise.mli | 160 ----------- infer/src/absint/Checkers.ml | 8 +- infer/src/absint/Checkers.mli | 2 +- infer/src/backend/InferPrint.ml | 62 ++-- infer/src/backend/inferconfig.ml | 17 +- infer/src/backend/inferconfig.mli | 6 +- infer/src/backend/interproc.ml | 2 +- infer/src/backend/printer.ml | 2 +- infer/src/backend/reporting.ml | 13 +- infer/src/backend/state.ml | 2 +- infer/src/backend/symExec.ml | 2 +- infer/src/base/CommandLineOption.ml | 38 ++- infer/src/base/CommandLineOption.mli | 15 +- infer/src/base/Config.ml | 57 ++-- infer/src/base/Config.mli | 6 - infer/src/base/IssueType.ml | 271 ++++++++++++++++++ infer/src/base/IssueType.mli | 200 +++++++++++++ .../src/bufferoverrun/bufferOverrunChecker.ml | 4 +- infer/src/checkers/NullabilitySuggest.ml | 2 +- infer/src/checkers/Siof.ml | 2 +- infer/src/checkers/ThreadSafety.ml | 2 +- infer/src/checkers/immutableChecker.ml | 2 +- infer/src/checkers/liveness.ml | 2 +- infer/src/checkers/printfArgs.ml | 4 +- infer/src/checkers/repeatedCallsChecker.ml | 2 +- infer/src/clang/cFrontend_errors.ml | 2 +- infer/src/eradicate/typeErr.ml | 38 +-- infer/src/eradicate/typeErr.mli | 2 +- infer/src/labs/ResourceLeaks.ml | 2 +- infer/src/quandary/TaintAnalysis.ml | 2 +- infer/src/unit/DifferentialFiltersTests.ml | 4 +- infer/tests/codetoanalyze/java/.inferconfig | 2 +- .../codetoanalyze/java/quandary/issues.exp | 44 +-- .../codetoanalyze/objcpp/linters/Makefile | 2 +- 40 files changed, 719 insertions(+), 642 deletions(-) create mode 100644 infer/src/base/IssueType.ml create mode 100644 infer/src/base/IssueType.mli diff --git a/infer/src/.merlin b/infer/src/.merlin index 3a5f6ac8b..d130101bc 100644 --- a/infer/src/.merlin +++ b/infer/src/.merlin @@ -15,7 +15,7 @@ PKG xmlm PKG yojson PKG zip FLG -principal -safe-string -short-paths -strict-formats -strict-sequence -FLG -w +a-4-9-40-41-42-45-48-60 +FLG -w +a-4-9-40-41-42-44-45-48-60 FLG -open InferBaseStdlib -open InferGenerated -open InferModules S backend S base diff --git a/infer/src/IR/Errlog.ml b/infer/src/IR/Errlog.ml index ce3b8ceee..cee304a33 100644 --- a/infer/src/IR/Errlog.ml +++ b/infer/src/IR/Errlog.ml @@ -67,7 +67,7 @@ type node_id_key = {node_id: int; node_key: int} type err_key = { err_kind: Exceptions.err_kind ; in_footprint: bool - ; err_name: Localise.t + ; err_name: IssueType.t ; err_desc: Localise.error_desc ; severity: string } [@@deriving compare] @@ -104,7 +104,7 @@ module ErrLogHash = struct (key.err_kind, key.in_footprint, key.err_name, Localise.error_desc_hash key.err_desc) let equal key1 key2 = - [%compare.equal : Exceptions.err_kind * bool * Localise.t] + [%compare.equal : Exceptions.err_kind * bool * IssueType.t] (key1.err_kind, key1.in_footprint, key1.err_name) (key2.err_kind, key2.in_footprint, key2.err_name) && Localise.error_desc_equal key1.err_desc key2.err_desc @@ -147,7 +147,7 @@ let size filter (err_log: t) = let pp_errors fmt (errlog: t) = let f key _ = if Exceptions.equal_err_kind key.err_kind Exceptions.Kerror then - F.fprintf fmt "%a@ " Localise.pp key.err_name + F.fprintf fmt "%a@ " IssueType.pp key.err_name in ErrLogHash.iter f errlog @@ -155,7 +155,7 @@ let pp_errors fmt (errlog: t) = let pp_warnings fmt (errlog: t) = let f key _ = if Exceptions.equal_err_kind key.err_kind Exceptions.Kwarning then - F.fprintf fmt "%a %a@ " Localise.pp key.err_name Localise.pp_error_desc key.err_desc + F.fprintf fmt "%a %a@ " IssueType.pp key.err_name Localise.pp_error_desc key.err_desc in ErrLogHash.iter f errlog @@ -170,7 +170,7 @@ let pp_html source path_to_root fmt (errlog: t) = in let pp_err_log do_fp ek key err_datas = if Exceptions.equal_err_kind key.err_kind ek && Bool.equal do_fp key.in_footprint then - F.fprintf fmt "
%a %a %a" Localise.pp key.err_name Localise.pp_error_desc key.err_desc + F.fprintf fmt "
%a %a %a" IssueType.pp key.err_name Localise.pp_error_desc key.err_desc pp_eds err_datas in F.fprintf fmt "%aERRORS DURING FOOTPRINT@\n" Io_infer.Html.pp_hline () ; @@ -263,7 +263,7 @@ let log_issue err_kind err_log loc (node_id, node_key) session ltr ?linters_def_ if err_kind <> Exceptions.Kerror then let warn_str = let pp fmt = - Format.fprintf fmt "%s %a" (Localise.to_issue_id err_name) Localise.pp_error_desc desc + Format.fprintf fmt "%s %a" err_name.IssueType.unique_id Localise.pp_error_desc desc in F.asprintf "%t" pp in @@ -295,8 +295,8 @@ module Err_table = struct let pp_stats_footprint ekind fmt (err_table: err_log) = let err_name_map = ref String.Map.empty in (* map error name to count *) - let count_err (err_name: Localise.t) n = - let err_string = Localise.to_issue_id err_name in + let count_err (err_name: IssueType.t) n = + let err_string = err_name.IssueType.unique_id in let count = try String.Map.find_exn !err_name_map err_string with Not_found -> 0 diff --git a/infer/src/IR/Errlog.mli b/infer/src/IR/Errlog.mli index 3095b6e57..39ea0f44d 100644 --- a/infer/src/IR/Errlog.mli +++ b/infer/src/IR/Errlog.mli @@ -41,7 +41,7 @@ type node_id_key = private {node_id: int; node_key: int} type err_key = private { err_kind: Exceptions.err_kind ; in_footprint: bool - ; err_name: Localise.t + ; err_name: IssueType.t ; err_desc: Localise.error_desc ; severity: string } [@@deriving compare] diff --git a/infer/src/IR/Exceptions.ml b/infer/src/IR/Exceptions.ml index e29f22af1..aadfded95 100644 --- a/infer/src/IR/Exceptions.ml +++ b/infer/src/IR/Exceptions.ml @@ -153,9 +153,9 @@ exception Wrong_argument_number of L.ml_loc let recognize_exception exn = let err_name, desc, (ml_loc_opt: L.ml_loc option), visibility, severity, force_kind, eclass = match exn with - (* all the names of Exn_user errors must be defined in Localise *) + (* all the static names of errors must be defined in Config.IssueType *) | Abduction_case_not_implemented ml_loc - -> ( Localise.from_string "Abduction_case_not_implemented" + -> ( IssueType.abduction_case_not_implemented , Localise.no_desc , Some ml_loc , Exn_developer @@ -163,12 +163,12 @@ let recognize_exception exn = , None , Nocat ) | Context_leak (desc, _) - -> (Localise.context_leak, desc, None, Exn_user, High, None, Nocat) + -> (IssueType.context_leak, desc, None, Exn_user, High, None, Nocat) | Analysis_stops (desc, ml_loc_opt) -> let visibility = if Config.analysis_stops then Exn_user else Exn_developer in - (Localise.analysis_stops, desc, ml_loc_opt, visibility, Medium, None, Nocat) + (IssueType.analysis_stops, desc, ml_loc_opt, visibility, Medium, None, Nocat) | Array_of_pointsto ml_loc - -> ( Localise.from_string "Array_of_pointsto" + -> ( IssueType.array_of_pointsto , Localise.no_desc , Some ml_loc , Exn_developer @@ -176,47 +176,31 @@ let recognize_exception exn = , None , Nocat ) | Array_out_of_bounds_l1 (desc, ml_loc) - -> (Localise.array_out_of_bounds_l1, desc, Some ml_loc, Exn_user, High, Some Kerror, Checker) + -> (IssueType.array_out_of_bounds_l1, desc, Some ml_loc, Exn_user, High, Some Kerror, Checker) | Array_out_of_bounds_l2 (desc, ml_loc) - -> (Localise.array_out_of_bounds_l2, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.array_out_of_bounds_l2, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Array_out_of_bounds_l3 (desc, ml_loc) - -> (Localise.array_out_of_bounds_l3, desc, Some ml_loc, Exn_developer, Medium, None, Nocat) + -> (IssueType.array_out_of_bounds_l3, desc, Some ml_loc, Exn_developer, Medium, None, Nocat) | Assert_failure (f, l, c) -> let ml_loc = (f, l, c, c) in - ( Localise.from_string "Assert_failure" - , Localise.no_desc - , Some ml_loc - , Exn_developer - , High - , None - , Nocat ) + (IssueType.assert_failure, Localise.no_desc, Some ml_loc, Exn_developer, High, None, Nocat) | Bad_footprint ml_loc - -> ( Localise.from_string "Bad_footprint" - , Localise.no_desc - , Some ml_loc - , Exn_developer - , Low - , None - , Nocat ) + -> (IssueType.bad_footprint, Localise.no_desc, Some ml_loc, Exn_developer, Low, None, Nocat) | Cannot_star ml_loc - -> ( Localise.from_string "Cannot_star" - , Localise.no_desc - , Some ml_loc - , Exn_developer - , Low - , None - , Nocat ) + -> (IssueType.cannot_star, Localise.no_desc, Some ml_loc, Exn_developer, Low, None, Nocat) | Class_cast_exception (desc, ml_loc) - -> (Localise.class_cast_exception, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.class_cast_exception, desc, Some ml_loc, Exn_user, High, None, Prover) | Codequery desc - -> (Localise.from_string "Codequery", desc, None, Exn_user, High, None, Prover) + -> (IssueType.codequery, desc, None, Exn_user, High, None, Prover) | Comparing_floats_for_equality (desc, ml_loc) - -> (Localise.comparing_floats_for_equality, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.comparing_floats_for_equality, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Condition_always_true_false (desc, b, ml_loc) - -> let name = if b then Localise.condition_always_true else Localise.condition_always_false in + -> let name = + if b then IssueType.condition_always_true else IssueType.condition_always_false + in (name, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Custom_error (error_msg, desc) - -> (Localise.from_string error_msg, desc, None, Exn_user, High, None, Checker) + -> (IssueType.from_string error_msg, desc, None, Exn_user, High, None, Checker) | Dangling_pointer_dereference (dko, desc, ml_loc) -> let visibility = match dko with @@ -225,43 +209,49 @@ let recognize_exception exn = | None -> Exn_developer in - (Localise.dangling_pointer_dereference, desc, Some ml_loc, visibility, High, None, Prover) + (IssueType.dangling_pointer_dereference, desc, Some ml_loc, visibility, High, None, Prover) | Deallocate_stack_variable desc - -> (Localise.deallocate_stack_variable, desc, None, Exn_user, High, None, Prover) + -> (IssueType.deallocate_stack_variable, desc, None, Exn_user, High, None, Prover) | Deallocate_static_memory desc - -> (Localise.deallocate_static_memory, desc, None, Exn_user, High, None, Prover) + -> (IssueType.deallocate_static_memory, desc, None, Exn_user, High, None, Prover) | Deallocation_mismatch (desc, ml_loc) - -> (Localise.deallocation_mismatch, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.deallocation_mismatch, desc, Some ml_loc, Exn_user, High, None, Prover) | Divide_by_zero (desc, ml_loc) - -> (Localise.divide_by_zero, desc, Some ml_loc, Exn_user, High, Some Kerror, Checker) + -> (IssueType.divide_by_zero, desc, Some ml_loc, Exn_user, High, Some Kerror, Checker) | Double_lock (desc, ml_loc) - -> (Localise.double_lock, desc, Some ml_loc, Exn_user, High, Some Kerror, Prover) + -> (IssueType.double_lock, desc, Some ml_loc, Exn_user, High, Some Kerror, Prover) | Eradicate (kind_s, desc) - -> (Localise.from_string kind_s, desc, None, Exn_user, High, None, Prover) + -> (IssueType.from_string kind_s, desc, None, Exn_user, High, None, Prover) | Empty_vector_access (desc, ml_loc) - -> (Localise.empty_vector_access, desc, Some ml_loc, Exn_user, High, Some Kerror, Prover) + -> (IssueType.empty_vector_access, desc, Some ml_loc, Exn_user, High, Some Kerror, Prover) | Field_not_null_checked (desc, ml_loc) - -> (Localise.field_not_null_checked, desc, Some ml_loc, Exn_user, Medium, Some Kwarning, Nocat) + -> ( IssueType.field_not_null_checked + , desc + , Some ml_loc + , Exn_user + , Medium + , Some Kwarning + , Nocat ) | Frontend_warning ((name, hum), desc, ml_loc) - -> (Localise.from_string name ?hum, desc, Some ml_loc, Exn_user, Medium, None, Linters) + -> (IssueType.from_string name ?hum, desc, Some ml_loc, Exn_user, Medium, None, Linters) | Checkers (kind_s, desc) - -> (Localise.from_string kind_s, desc, None, Exn_user, High, None, Prover) + -> (IssueType.from_string kind_s, desc, None, Exn_user, High, None, Prover) | Null_dereference (desc, ml_loc) - -> (Localise.null_dereference, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.null_dereference, desc, Some ml_loc, Exn_user, High, None, Prover) | Null_test_after_dereference (desc, ml_loc) - -> (Localise.null_test_after_dereference, desc, Some ml_loc, Exn_user, High, None, Nocat) + -> (IssueType.null_test_after_dereference, desc, Some ml_loc, Exn_user, High, None, Nocat) | Pointer_size_mismatch (desc, ml_loc) - -> (Localise.pointer_size_mismatch, desc, Some ml_loc, Exn_user, High, Some Kerror, Checker) + -> (IssueType.pointer_size_mismatch, desc, Some ml_loc, Exn_user, High, Some Kerror, Checker) | Inherently_dangerous_function desc - -> (Localise.inherently_dangerous_function, desc, None, Exn_developer, Medium, None, Nocat) + -> (IssueType.inherently_dangerous_function, desc, None, Exn_developer, Medium, None, Nocat) | Internal_error desc - -> (Localise.from_string "Internal_error", desc, None, Exn_developer, High, None, Nocat) + -> (IssueType.internal_error, desc, None, Exn_developer, High, None, Nocat) | Java_runtime_exception (exn_name, _, desc) -> let exn_str = Typ.Name.name exn_name in - (Localise.from_string exn_str, desc, None, Exn_user, High, None, Prover) + (IssueType.from_string exn_str, desc, None, Exn_user, High, None, Prover) | Leak (fp_part, _, (exn_vis, error_desc), done_array_abstraction, resource, ml_loc) -> if done_array_abstraction then - ( Localise.from_string "Leak_after_array_abstraction" + ( IssueType.leak_after_array_abstraction , error_desc , Some ml_loc , Exn_developer @@ -269,39 +259,27 @@ let recognize_exception exn = , None , Prover ) else if fp_part then - ( Localise.from_string "Leak_in_footprint" - , error_desc - , Some ml_loc - , Exn_developer - , High - , None - , Prover ) + (IssueType.leak_in_footprint, error_desc, Some ml_loc, Exn_developer, High, None, Prover) else let loc_str = match resource with | PredSymb.Rmemory _ - -> Localise.memory_leak + -> IssueType.memory_leak | PredSymb.Rfile - -> Localise.resource_leak + -> IssueType.resource_leak | PredSymb.Rlock - -> Localise.resource_leak + -> IssueType.resource_leak | PredSymb.Rignore - -> Localise.memory_leak + -> IssueType.memory_leak in (loc_str, error_desc, Some ml_loc, exn_vis, High, None, Prover) | Missing_fld (fld, ml_loc) -> let desc = Localise.verbatim_desc (Typ.Fieldname.to_full_string fld) in - ( Localise.from_string "Missing_fld" ~hum:"Missing Field" - , desc - , Some ml_loc - , Exn_developer - , Medium - , None - , Nocat ) + (IssueType.missing_fld, desc, Some ml_loc, Exn_developer, Medium, None, Nocat) | Premature_nil_termination (desc, ml_loc) - -> (Localise.premature_nil_termination, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.premature_nil_termination, desc, Some ml_loc, Exn_user, High, None, Prover) | Parameter_not_null_checked (desc, ml_loc) - -> ( Localise.parameter_not_null_checked + -> ( IssueType.parameter_not_null_checked , desc , Some ml_loc , Exn_user @@ -309,9 +287,9 @@ let recognize_exception exn = , Some Kwarning , Nocat ) | Precondition_not_found (desc, ml_loc) - -> (Localise.precondition_not_found, desc, Some ml_loc, Exn_developer, Low, None, Nocat) + -> (IssueType.precondition_not_found, desc, Some ml_loc, Exn_developer, Low, None, Nocat) | Precondition_not_met (desc, ml_loc) - -> ( Localise.precondition_not_met + -> ( IssueType.precondition_not_met , desc , Some ml_loc , Exn_developer @@ -320,9 +298,9 @@ let recognize_exception exn = , Nocat ) (* always a warning *) | Retain_cycle (_, desc, ml_loc) - -> (Localise.retain_cycle, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.retain_cycle, desc, Some ml_loc, Exn_user, High, None, Prover) | Registered_observer_being_deallocated (desc, ml_loc) - -> ( Localise.registered_observer_being_deallocated + -> ( IssueType.registered_observer_being_deallocated , desc , Some ml_loc , Exn_user @@ -330,9 +308,9 @@ let recognize_exception exn = , Some Kerror , Nocat ) | Return_expression_required (desc, ml_loc) - -> (Localise.return_expression_required, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.return_expression_required, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Stack_variable_address_escape (desc, ml_loc) - -> ( Localise.stack_variable_address_escape + -> ( IssueType.stack_variable_address_escape , desc , Some ml_loc , Exn_user @@ -340,18 +318,18 @@ let recognize_exception exn = , Some Kerror , Nocat ) | Return_statement_missing (desc, ml_loc) - -> (Localise.return_statement_missing, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.return_statement_missing, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Return_value_ignored (desc, ml_loc) - -> (Localise.return_value_ignored, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.return_value_ignored, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | SymOp.Analysis_failure_exe _ - -> (Localise.from_string "Failure_exe", Localise.no_desc, None, Exn_system, Low, None, Nocat) + -> (IssueType.failure_exe, Localise.no_desc, None, Exn_system, Low, None, Nocat) | Skip_function desc - -> (Localise.skip_function, desc, None, Exn_developer, Low, None, Nocat) + -> (IssueType.skip_function, desc, None, Exn_developer, Low, None, Nocat) | Skip_pointer_dereference (desc, ml_loc) - -> (Localise.skip_pointer_dereference, desc, Some ml_loc, Exn_user, Medium, Some Kinfo, Nocat) + -> (IssueType.skip_pointer_dereference, desc, Some ml_loc, Exn_user, Medium, Some Kinfo, Nocat) (* always an info *) | Symexec_memory_error ml_loc - -> ( Localise.from_string "Symexec_memory_error" ~hum:"Symbolic Execution Memory Error" + -> ( IssueType.symexec_memory_error , Localise.no_desc , Some ml_loc , Exn_developer @@ -359,9 +337,9 @@ let recognize_exception exn = , None , Nocat ) | Uninitialized_value (desc, ml_loc) - -> (Localise.uninitialized_value, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.uninitialized_value, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Unary_minus_applied_to_unsigned_expression (desc, ml_loc) - -> ( Localise.unary_minus_applied_to_unsigned_expression + -> ( IssueType.unary_minus_applied_to_unsigned_expression , desc , Some ml_loc , Exn_user @@ -369,21 +347,15 @@ let recognize_exception exn = , None , Nocat ) | Unknown_proc - -> ( Localise.from_string "Unknown_proc" ~hum:"Unknown Procedure" - , Localise.no_desc - , None - , Exn_developer - , Low - , None - , Nocat ) + -> (IssueType.unknown_proc, Localise.no_desc, None, Exn_developer, Low, None, Nocat) | Unreachable_code_after (desc, ml_loc) - -> (Localise.unreachable_code_after, desc, Some ml_loc, Exn_user, Medium, None, Nocat) + -> (IssueType.unreachable_code_after, desc, Some ml_loc, Exn_user, Medium, None, Nocat) | Unsafe_guarded_by_access (desc, ml_loc) - -> (Localise.unsafe_guarded_by_access, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.unsafe_guarded_by_access, desc, Some ml_loc, Exn_user, High, None, Prover) | Use_after_free (desc, ml_loc) - -> (Localise.use_after_free, desc, Some ml_loc, Exn_user, High, None, Prover) + -> (IssueType.use_after_free, desc, Some ml_loc, Exn_user, High, None, Prover) | Wrong_argument_number ml_loc - -> ( Localise.from_string "Wrong_argument_number" ~hum:"Wrong Argument Number" + -> ( IssueType.wrong_argument_number , Localise.no_desc , Some ml_loc , Exn_developer @@ -402,7 +374,7 @@ let print_exception_html s exn = match ml_loc_opt with None -> "" | Some ml_loc -> " " ^ L.ml_loc_to_string ml_loc in let desc_str = F.asprintf "%a" Localise.pp_error_desc desc in - L.d_strln_color Red (s ^ Localise.to_issue_id err_name ^ " " ^ desc_str ^ ml_loc_string) + L.d_strln_color Red (s ^ err_name.IssueType.unique_id ^ " " ^ desc_str ^ ml_loc_string) (** string describing an error kind *) let err_kind_string = function @@ -436,7 +408,7 @@ let pp_err ~node_key loc ekind ex_name desc ml_loc_opt fmt () = let kind = err_kind_string (if equal_err_kind ekind Kinfo then Kwarning else ekind) in let pp_key fmt k = if print_key then F.fprintf fmt " key: %d " k else () in F.fprintf fmt "%a:%d: %s: %a %a%a%a@\n" SourceFile.pp loc.Location.file loc.Location.line kind - Localise.pp ex_name Localise.pp_error_desc desc pp_key node_key L.pp_ml_loc_opt ml_loc_opt + IssueType.pp ex_name Localise.pp_error_desc desc pp_key node_key L.pp_ml_loc_opt ml_loc_opt (** Return true if the exception is not serious and should be handled in timeout mode *) let handle_exception exn = diff --git a/infer/src/IR/Exceptions.mli b/infer/src/IR/Exceptions.mli index c8e850cb0..66f607d3b 100644 --- a/infer/src/IR/Exceptions.mli +++ b/infer/src/IR/Exceptions.mli @@ -134,6 +134,7 @@ exception Skip_pointer_dereference of Localise.error_desc * Logging.ml_loc exception Stack_variable_address_escape of Localise.error_desc * Logging.ml_loc exception Symexec_memory_error of Logging.ml_loc + exception Unary_minus_applied_to_unsigned_expression of Localise.error_desc * Logging.ml_loc exception Uninitialized_value of Localise.error_desc * Logging.ml_loc @@ -161,13 +162,13 @@ val print_exception_html : string -> exn -> unit (** print a description of the exception to the html output *) val pp_err : - node_key:int -> Location.t -> err_kind -> Localise.t -> Localise.error_desc + node_key:int -> Location.t -> err_kind -> IssueType.t -> Localise.error_desc -> Logging.ml_loc option -> Format.formatter -> unit -> unit (** pretty print an error *) val recognize_exception : exn - -> Localise.t + -> IssueType.t * Localise.error_desc * Logging.ml_loc option * visibility diff --git a/infer/src/IR/Localise.ml b/infer/src/IR/Localise.ml index b755df9ad..77a4ebe55 100644 --- a/infer/src/IR/Localise.ml +++ b/infer/src/IR/Localise.ml @@ -15,191 +15,6 @@ open! IStd module F = Format module MF = MarkupFormatter -type t = string * string [@@deriving compare] - -(* issue_id, human_readable *) - -let equal = [%compare.equal : t] - -(** create from an ordinary string *) -let from_string ?hum s : t = - let prettify () = - String.lowercase s |> String.split ~on:'_' |> List.map ~f:String.capitalize - |> String.concat ~sep:" " |> String.strip - in - (s, match hum with Some str -> str | _ -> prettify ()) - -(** return the id of an issue *) -let to_issue_id (s, _) = s - -let to_human_readable_string (_, s) = s - -(** pretty print a localised string *) -let pp fmt t = Format.fprintf fmt "%s" (to_issue_id t) - -let analysis_stops = from_string "ANALYSIS_STOPS" - -let array_out_of_bounds_l1 = from_string "ARRAY_OUT_OF_BOUNDS_L1" - -let array_out_of_bounds_l2 = from_string "ARRAY_OUT_OF_BOUNDS_L2" - -let array_out_of_bounds_l3 = from_string "ARRAY_OUT_OF_BOUNDS_L3" - -let buffer_overrun = from_string "BUFFER_OVERRUN" - -let checkers_access_global = from_string "CHECKERS_ACCESS_GLOBAL" - -let checkers_immutable_cast = from_string "CHECKERS_IMMUTABLE_CAST" - -let checkers_print_c_call = from_string "CHECKERS_PRINT_C_CALL" - -let checkers_print_objc_method_calls = from_string "CHECKERS_PRINT_OBJC_METHOD_CALLS" - -let checkers_printf_args = from_string "CHECKERS_PRINTF_ARGS" - -let checkers_repeated_calls = from_string "CHECKERS_REPEATED_CALLS" - -let checkers_trace_calls_sequence = from_string "CHECKERS_TRACE_CALLS_SEQUENCE" - -let class_cast_exception = from_string "CLASS_CAST_EXCEPTION" - -let cluster_callback = from_string "CLUSTER_CALLBACK" - -let comparing_floats_for_equality = from_string "COMPARING_FLOAT_FOR_EQUALITY" - -let condition_always_false = from_string "CONDITION_ALWAYS_FALSE" - -let condition_always_true = from_string "CONDITION_ALWAYS_TRUE" - -let context_leak = from_string "CONTEXT_LEAK" - -let dangling_pointer_dereference = from_string "DANGLING_POINTER_DEREFERENCE" - -let dead_store = from_string "DEAD_STORE" - -let deallocate_stack_variable = from_string "DEALLOCATE_STACK_VARIABLE" - -let deallocate_static_memory = from_string "DEALLOCATE_STATIC_MEMORY" - -let deallocation_mismatch = from_string "DEALLOCATION_MISMATCH" - -let divide_by_zero = from_string "DIVIDE_BY_ZERO" - -let double_lock = from_string "DOUBLE_LOCK" - -let empty_vector_access = from_string "EMPTY_VECTOR_ACCESS" - -let eradicate_condition_redundant = - from_string "ERADICATE_CONDITION_REDUNDANT" ~hum:"Condition Redundant" - -let eradicate_condition_redundant_nonnull = - from_string "ERADICATE_CONDITION_REDUNDANT_NONNULL" ~hum:"Condition Redundant Non-Null" - -let eradicate_field_not_initialized = - from_string "ERADICATE_FIELD_NOT_INITIALIZED" ~hum:"Field Not Initialized" - -let eradicate_field_not_mutable = - from_string "ERADICATE_FIELD_NOT_MUTABLE" ~hum:"Field Not Mutable" - -let eradicate_field_not_nullable = - from_string "ERADICATE_FIELD_NOT_NULLABLE" ~hum:"Field Not Nullable" - -let eradicate_field_over_annotated = - from_string "ERADICATE_FIELD_OVER_ANNOTATED" ~hum:"Field Over Annotated" - -let eradicate_field_value_absent = - from_string "ERADICATE_FIELD_VALUE_ABSENT" ~hum:"Field Value Absent" - -let eradicate_inconsistent_subclass_parameter_annotation = - from_string "ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION" - ~hum:"Inconsistent Subclass Parameter Annotation" - -let eradicate_inconsistent_subclass_return_annotation = - from_string "ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION" - ~hum:"Inconsistent Subclass Return Annotation" - -let eradicate_null_field_access = - from_string "ERADICATE_NULL_FIELD_ACCESS" ~hum:"Null Field Access" - -let eradicate_null_method_call = from_string "ERADICATE_NULL_METHOD_CALL" ~hum:"Null Method Call" - -let eradicate_parameter_not_nullable = - from_string "ERADICATE_PARAMETER_NOT_NULLABLE" ~hum:"Parameter Not Nullable" - -let eradicate_parameter_value_absent = - from_string "ERADICATE_PARAMETER_VALUE_ABSENT" ~hum:"Parameter Value Absent" - -let eradicate_return_not_nullable = - from_string "ERADICATE_RETURN_NOT_NULLABLE" ~hum:"Return Not Nullable" - -let eradicate_return_over_annotated = - from_string "ERADICATE_RETURN_OVER_ANNOTATED" ~hum:"Return Over Annotated" - -let eradicate_return_value_not_present = - from_string "ERADICATE_RETURN_VALUE_NOT_PRESENT" ~hum:"Return Value Not Present" - -let eradicate_value_not_present = - from_string "ERADICATE_VALUE_NOT_PRESENT" ~hum:"Value Not Present" - -let field_should_be_nullable = from_string "FIELD_SHOULD_BE_NULLABLE" - -let field_not_null_checked = from_string "IVAR_NOT_NULL_CHECKED" - -let inherently_dangerous_function = from_string "INHERENTLY_DANGEROUS_FUNCTION" - -let memory_leak = from_string "MEMORY_LEAK" - -let null_dereference = from_string "NULL_DEREFERENCE" - -let null_test_after_dereference = from_string "NULL_TEST_AFTER_DEREFERENCE" - -let parameter_not_null_checked = from_string "PARAMETER_NOT_NULL_CHECKED" - -let pointer_size_mismatch = from_string "POINTER_SIZE_MISMATCH" - -let precondition_not_found = from_string "PRECONDITION_NOT_FOUND" - -let precondition_not_met = from_string "PRECONDITION_NOT_MET" - -let premature_nil_termination = from_string "PREMATURE_NIL_TERMINATION_ARGUMENT" - -let proc_callback = from_string "PROC_CALLBACK" ~hum:"Procedure Callback" - -let quandary_taint_error = from_string "QUANDARY_TAINT_ERROR" - -let registered_observer_being_deallocated = from_string "REGISTERED_OBSERVER_BEING_DEALLOCATED" - -let resource_leak = from_string "RESOURCE_LEAK" - -let retain_cycle = from_string "RETAIN_CYCLE" - -let return_expression_required = from_string "RETURN_EXPRESSION_REQUIRED" - -let return_statement_missing = from_string "RETURN_STATEMENT_MISSING" - -let return_value_ignored = from_string "RETURN_VALUE_IGNORED" - -let skip_function = from_string "SKIP_FUNCTION" - -let skip_pointer_dereference = from_string "SKIP_POINTER_DEREFERENCE" - -let stack_variable_address_escape = from_string "STACK_VARIABLE_ADDRESS_ESCAPE" - -let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO" - -let thread_safety_violation = from_string "THREAD_SAFETY_VIOLATION" - -let unary_minus_applied_to_unsigned_expression = - from_string "UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" - -let uninitialized_value = from_string "UNINITIALIZED_VALUE" - -let unreachable_code_after = from_string "UNREACHABLE_CODE" - -let unsafe_guarded_by_access = from_string "UNSAFE_GUARDED_BY_ACCESS" - -let use_after_free = from_string "USE_AFTER_FREE" - module Tags = struct type t = (string * string) list [@@deriving compare] diff --git a/infer/src/IR/Localise.mli b/infer/src/IR/Localise.mli index 8960b1cf0..cb791e86e 100644 --- a/infer/src/IR/Localise.mli +++ b/infer/src/IR/Localise.mli @@ -12,166 +12,6 @@ open! IStd (** Support for localisation *) -(** type of string used for localisation *) -type t [@@deriving compare] - -val equal : t -> t -> bool - -val pp : Format.formatter -> t -> unit -(** pretty print a localised string *) - -val from_string : ?hum:string -> string -> t -(** create from an ordinary string *) - -val to_issue_id : t -> string -(** return the id of an issue *) - -val to_human_readable_string : t -> string -(** return the human-readable name of an issue *) - -val analysis_stops : t - -val array_out_of_bounds_l1 : t - -val array_out_of_bounds_l2 : t - -val array_out_of_bounds_l3 : t - -val buffer_overrun : t - -val checkers_access_global : t - -val checkers_immutable_cast : t - -val checkers_print_c_call : t - -val checkers_print_objc_method_calls : t - -val checkers_printf_args : t - -val checkers_repeated_calls : t - -val checkers_trace_calls_sequence : t - -val class_cast_exception : t - -val cluster_callback : t - -val comparing_floats_for_equality : t - -val condition_always_false : t - -val condition_always_true : t - -val context_leak : t - -val dangling_pointer_dereference : t - -val dead_store : t - -val deallocate_stack_variable : t - -val deallocate_static_memory : t - -val deallocation_mismatch : t - -val divide_by_zero : t - -val double_lock : t - -val empty_vector_access : t - -val eradicate_condition_redundant : t - -val eradicate_condition_redundant_nonnull : t - -val eradicate_field_not_initialized : t - -val eradicate_field_not_mutable : t - -val eradicate_field_not_nullable : t - -val eradicate_field_over_annotated : t - -val eradicate_field_value_absent : t - -val eradicate_inconsistent_subclass_parameter_annotation : t - -val eradicate_inconsistent_subclass_return_annotation : t - -val eradicate_null_field_access : t - -val eradicate_null_method_call : t - -val eradicate_parameter_not_nullable : t - -val eradicate_parameter_value_absent : t - -val eradicate_return_not_nullable : t - -val eradicate_return_over_annotated : t - -val eradicate_return_value_not_present : t - -val eradicate_value_not_present : t - -val field_should_be_nullable : t - -val field_not_null_checked : t - -val inherently_dangerous_function : t - -val memory_leak : t - -val null_dereference : t - -val null_test_after_dereference : t - -val parameter_not_null_checked : t - -val pointer_size_mismatch : t - -val precondition_not_found : t - -val precondition_not_met : t - -val premature_nil_termination : t - -val proc_callback : t - -val quandary_taint_error : t - -val registered_observer_being_deallocated : t - -val resource_leak : t - -val retain_cycle : t - -val return_expression_required : t - -val return_statement_missing : t - -val return_value_ignored : t - -val skip_function : t - -val skip_pointer_dereference : t - -val stack_variable_address_escape : t - -val static_initialization_order_fiasco : t -val thread_safety_violation : t - -val unary_minus_applied_to_unsigned_expression : t - -val uninitialized_value : t - -val unreachable_code_after : t - -val unsafe_guarded_by_access : t - -val use_after_free : t - module Tags : sig type t diff --git a/infer/src/absint/Checkers.ml b/infer/src/absint/Checkers.ml index 56046244d..3677a36e5 100644 --- a/infer/src/absint/Checkers.ml +++ b/infer/src/absint/Checkers.ml @@ -42,7 +42,7 @@ module ST = struct Localise.custom_desc_with_advice description (Option.value ~default:"" advice) [("always_report", string_of_bool always_report)] in - let exn = exception_kind (Localise.to_issue_id kind) localized_description in + let exn = exception_kind kind.IssueType.unique_id localized_description in let proc_attributes = Specs.pdesc_resolve_attributes proc_desc in (* Errors can be suppressed with annotations. An error of kind CHECKER_ERROR_NAME can be suppressed with the following annotations: @@ -56,11 +56,11 @@ module ST = struct let normalized_equal s1 s2 = String.equal (normalize s1) (normalize s2) in let is_parameter_suppressed = String.is_suffix a.class_name ~suffix:Annotations.suppress_lint - && List.mem ~equal:normalized_equal a.parameters (Localise.to_issue_id kind) + && List.mem ~equal:normalized_equal a.parameters kind.IssueType.unique_id in let is_annotation_suppressed = String.is_suffix - ~suffix:(normalize (drop_prefix (Localise.to_issue_id kind))) + ~suffix:(normalize (drop_prefix kind.IssueType.unique_id)) (normalize a.class_name) in is_parameter_suppressed || is_annotation_suppressed @@ -104,7 +104,7 @@ module ST = struct origin_elements @ [Errlog.make_trace_element 0 loc description []] in if not suppressed then ( - L.progress "%s: %a: %s@\n" (Localise.to_issue_id kind) SourceFile.pp loc.Location.file + L.progress "%s: %a: %s@\n" kind.IssueType.unique_id SourceFile.pp loc.Location.file (Typ.Procname.to_string proc_name) ; L.progress "%s@." description ; Reporting.log_error_deprecated proc_name ~loc ~ltr:trace exn ) diff --git a/infer/src/absint/Checkers.mli b/infer/src/absint/Checkers.mli index 5bd852185..6971afbb5 100644 --- a/infer/src/absint/Checkers.mli +++ b/infer/src/absint/Checkers.mli @@ -14,7 +14,7 @@ open! IStd (** State that persists in the .specs files. *) module ST : sig val report_error : - Tenv.t -> Typ.Procname.t -> Procdesc.t -> Localise.t -> Location.t -> ?advice:string option + Tenv.t -> Typ.Procname.t -> Procdesc.t -> IssueType.t -> Location.t -> ?advice:string option -> ?field_name:Typ.Fieldname.t option -> ?origin_loc:Location.t option -> ?exception_kind:(string -> Localise.error_desc -> exn) -> ?always_report:bool -> string -> unit diff --git a/infer/src/backend/InferPrint.ml b/infer/src/backend/InferPrint.ml index 733d8318c..3be731e2b 100644 --- a/infer/src/backend/InferPrint.ml +++ b/infer/src/backend/InferPrint.ml @@ -206,32 +206,32 @@ end let should_report (issue_kind: Exceptions.err_kind) issue_type error_desc eclass = if not Config.filtering || Exceptions.equal_err_class eclass Exceptions.Linters then true else - let issue_kind_is_blacklisted = - match issue_kind with Kinfo -> true | Kerror | Kwarning | Kadvice | Klike -> false + let issue_kind_is_blacklisted = + match issue_kind with Kinfo -> true | Kerror | Kwarning | Kadvice | Klike -> false + in + if issue_kind_is_blacklisted then false + else + let issue_type_is_null_deref = + let null_deref_issue_types = + let open IssueType in + [ field_not_null_checked + ; null_dereference + ; parameter_not_null_checked + ; premature_nil_termination + ; empty_vector_access ] + in + List.mem ~equal:IssueType.equal null_deref_issue_types issue_type in - if issue_kind_is_blacklisted then false - else - let issue_type_is_null_deref = - let null_deref_issue_types = - let open Localise in - [ field_not_null_checked - ; null_dereference - ; parameter_not_null_checked - ; premature_nil_termination - ; empty_vector_access ] - in - List.mem ~equal:Localise.equal null_deref_issue_types issue_type + let issue_type_is_buffer_overrun = IssueType.(equal buffer_overrun) issue_type in + if issue_type_is_null_deref || issue_type_is_buffer_overrun then + let issue_bucket_is_high = + let issue_bucket = Localise.error_desc_get_bucket error_desc in + let high_buckets = Localise.BucketLevel.([b1; b2]) in + Option.value_map issue_bucket ~default:false ~f:(fun b -> + List.mem ~equal:String.equal high_buckets b ) in - let issue_type_is_buffer_overrun = Localise.equal issue_type Localise.buffer_overrun in - if issue_type_is_null_deref || issue_type_is_buffer_overrun then - let issue_bucket_is_high = - let issue_bucket = Localise.error_desc_get_bucket error_desc in - let high_buckets = Localise.BucketLevel.([b1; b2]) in - Option.value_map issue_bucket ~default:false ~f:(fun b -> - List.mem ~equal:String.equal high_buckets b ) - in - issue_bucket_is_high - else true + issue_bucket_is_high + else true module IssuesCsv = struct let csv_issues_id = ref 0 @@ -270,7 +270,7 @@ module IssuesCsv = struct Escape.escape_csv s in let kind = Exceptions.err_kind_string key.err_kind in - let type_str = Localise.to_issue_id key.err_name in + let type_str = key.err_name.IssueType.unique_id in let procedure_id = Typ.Procname.to_filename procname in let filename = SourceFile.to_string source_file in let always_report = @@ -331,7 +331,7 @@ module IssuesJson = struct -> (err_data.loc.Location.file, 0) in if SourceFile.is_invalid source_file then - failwithf "Invalid source file for %a %a@.Trace: %a@." Localise.pp key.err_name + failwithf "Invalid source file for %a %a@.Trace: %a@." IssueType.pp key.err_name Localise.pp_error_desc key.err_desc Errlog.pp_loc_trace err_data.loc_trace ; let should_report_source_file = not (SourceFile.is_infer_model source_file) || Config.debug_mode || Config.debug_exceptions @@ -341,7 +341,7 @@ module IssuesJson = struct && should_report key.err_kind key.err_name key.err_desc err_data.err_class then let kind = Exceptions.err_kind_string key.err_kind in - let bug_type = Localise.to_issue_id key.err_name in + let bug_type = key.err_name.IssueType.unique_id in let procedure_id = Typ.Procname.to_filename procname in let file = SourceFile.to_string source_file in let json_ml_loc = @@ -354,7 +354,7 @@ module IssuesJson = struct let visibility = Exceptions.string_of_visibility err_data.visibility in let qualifier = let base_qualifier = error_desc_to_plain_string key.err_desc in - if Localise.equal key.err_name Localise.resource_leak then + if IssueType.(equal resource_leak) key.err_name then match Errlog.compute_local_exception_line err_data.loc_trace with | None -> base_qualifier @@ -387,7 +387,7 @@ module IssuesJson = struct key.err_desc ; dotty= error_desc_to_dotty_string key.err_desc ; infer_source_loc= json_ml_loc - ; bug_type_hum= Localise.to_human_readable_string key.err_name + ; bug_type_hum= key.err_name.IssueType.hum ; linters_def_file= err_data.linters_def_file ; doc_url= err_data.doc_url ; traceview_id= None } @@ -571,7 +571,7 @@ module Stats = struct let process_err_log error_filter linereader err_log stats = let found_errors = ref false in let process_row (key: Errlog.err_key) (err_data: Errlog.err_data) = - let type_str = Localise.to_issue_id key.err_name in + let type_str = key.err_name.IssueType.unique_id in if key.in_footprint && error_filter key.err_desc key.err_name then match key.err_kind with | Exceptions.Kerror @@ -726,7 +726,7 @@ let error_filter filters proc_name file error_desc error_name = let always_report () = String.equal (Localise.error_desc_extract_tag_value error_desc "always_report") "true" in - (Config.write_html || not (Localise.equal error_name Localise.skip_function)) + (Config.write_html || not (IssueType.(equal skip_function) error_name)) && (filters.Inferconfig.path_filter file || always_report ()) && filters.Inferconfig.error_filter error_name && filters.Inferconfig.proc_filter proc_name diff --git a/infer/src/backend/inferconfig.ml b/infer/src/backend/inferconfig.ml index c7d4c8e8b..4fc26cdcf 100644 --- a/infer/src/backend/inferconfig.ml +++ b/infer/src/backend/inferconfig.ml @@ -9,12 +9,11 @@ open! IStd module CLOpt = CommandLineOption -module F = Format module L = Logging type path_filter = SourceFile.t -> bool -type error_filter = Localise.t -> bool +type error_filter = IssueType.t -> bool type proc_filter = Typ.Procname.t -> bool @@ -320,7 +319,7 @@ let filters_from_inferconfig inferconfig : filters = in let error_filter = function | error_name - -> let error_str = Localise.to_issue_id error_name in + -> let error_str = error_name.IssueType.unique_id in not (List.exists ~f:(String.equal error_str) inferconfig.suppress_errors) in {path_filter; error_filter; proc_filter= default_proc_filter} @@ -330,18 +329,6 @@ let create_filters analyzer = if not Config.filter_paths then do_not_filter else filters_from_inferconfig (load_filters analyzer) -(* Decide whether a checker or error type is enabled or disabled based on*) -(* white/black listing in .inferconfig and the default value *) -let is_checker_enabled checker_name = - (* no-filtering takes priority over both whitelist and blacklist *) - not Config.filtering - (* whitelist takes priority over blacklist *) - || List.mem ~equal:String.( = ) Config.enable_checks checker_name - (* if it's blacklisted and not whitelisted then it should be disabled *) - || not (List.mem ~equal:String.( = ) Config.disable_checks checker_name) - (* if it's not amond white/black listed then we use default value *) - && not (List.mem ~equal:String.( = ) Config.checks_disabled_by_default checker_name) - (* This function loads and list the path that are being filtered by the analyzer. The results *) (* are of the form: path/to/file.java -> {infer, checkers} meaning that analysis results will *) (* be reported on path/to/file.java both for infer and for the checkers *) diff --git a/infer/src/backend/inferconfig.mli b/infer/src/backend/inferconfig.mli index 6afcc3b0e..a13c22f3b 100644 --- a/infer/src/backend/inferconfig.mli +++ b/infer/src/backend/inferconfig.mli @@ -13,7 +13,7 @@ open! IStd type path_filter = SourceFile.t -> bool (** Filter type for an error name. *) -type error_filter = Localise.t -> bool +type error_filter = IssueType.t -> bool (** Filter type for a procedure name *) type proc_filter = Typ.Procname.t -> bool @@ -34,7 +34,3 @@ val modeled_expensive_matcher : (string -> bool) -> Typ.Procname.t -> bool val test : unit -> unit (** Load the config file and list the files to report on *) - -val is_checker_enabled : string -> bool -(** is_checker_enabled [error_name] is [true] if [error_name] is whitelisted in .inferconfig or if - it's enabled by default *) diff --git a/infer/src/backend/interproc.ml b/infer/src/backend/interproc.ml index 75c4001f3..6c1638f86 100644 --- a/infer/src/backend/interproc.ml +++ b/infer/src/backend/interproc.ml @@ -1269,7 +1269,7 @@ let perform_transition proc_cfg tenv proc_name = L.(debug Analysis Medium) "Error in collect_preconditions for %a@." Typ.Procname.pp proc_name ; let err_name, _, ml_loc_opt, _, _, _, _ = Exceptions.recognize_exception exn in - let err_str = "exception raised " ^ Localise.to_issue_id err_name in + let err_str = "exception raised " ^ err_name.IssueType.unique_id in L.(debug Analysis Medium) "Error: %s %a@." err_str L.pp_ml_loc_opt ml_loc_opt ; [] in transition_footprint_re_exe tenv proc_name joined_pres diff --git a/infer/src/backend/printer.ml b/infer/src/backend/printer.ml index bcc8baff1..fd44a5231 100644 --- a/infer/src/backend/printer.ml +++ b/infer/src/backend/printer.ml @@ -379,7 +379,7 @@ let create_table_err_per_line err_log = let err_per_line = Hashtbl.create 17 in let add_err (key: Errlog.err_key) (err_data: Errlog.err_data) = let err_str = - Localise.to_issue_id key.err_name ^ " " ^ F.asprintf "%a" Localise.pp_error_desc key.err_desc + key.err_name.IssueType.unique_id ^ " " ^ F.asprintf "%a" Localise.pp_error_desc key.err_desc in try let set = Hashtbl.find err_per_line err_data.loc.Location.line in diff --git a/infer/src/backend/reporting.ml b/infer/src/backend/reporting.ml index 76d20f7ca..b1dbe6642 100644 --- a/infer/src/backend/reporting.ml +++ b/infer/src/backend/reporting.ml @@ -8,7 +8,6 @@ *) open! IStd -module L = Logging type log_t = ?loc:Location.t -> ?node_id:int * int -> ?session:int -> ?ltr:Errlog.loc_trace @@ -26,15 +25,11 @@ let log_issue_from_errlog err_kind err_log ?loc ?node_id ?session ?ltr ?linters_ match session with None -> (State.get_session () :> int) | Some session -> session in let ltr = match ltr with None -> State.get_loc_trace () | Some ltr -> ltr in - let err_name = - match exn with - | Exceptions.Frontend_warning ((err_name, _), _, _) - -> err_name - | _ - -> let err_name, _, _, _, _, _, _ = Exceptions.recognize_exception exn in - Localise.to_issue_id err_name + let issue_type = + let err_name, _, _, _, _, _, _ = Exceptions.recognize_exception exn in + err_name in - if Inferconfig.is_checker_enabled err_name then + if not Config.filtering (* no-filtering takes priority *) || issue_type.IssueType.enabled then Errlog.log_issue err_kind err_log loc node_id session ltr ?linters_def_file ?doc_url exn let log_issue_from_summary err_kind summary ?loc ?node_id ?session ?ltr ?linters_def_file ?doc_url diff --git a/infer/src/backend/state.ml b/infer/src/backend/state.ml index 22a8fbf04..39304619a 100644 --- a/infer/src/backend/state.ml +++ b/infer/src/backend/state.ml @@ -319,7 +319,7 @@ let process_execution_failures (log_issue: log_issue) pname = match (fs.node_ok, fs.first_failure) with | 0, Some (loc, key, _, loc_trace, exn) when not Config.debug_exceptions -> let ex_name, _, ml_loc_opt, _, _, _, _ = Exceptions.recognize_exception exn in - let desc' = Localise.verbatim_desc ("exception: " ^ Localise.to_issue_id ex_name) in + let desc' = Localise.verbatim_desc ("exception: " ^ ex_name.IssueType.unique_id) in let exn' = Exceptions.Analysis_stops (desc', ml_loc_opt) in log_issue pname ~loc ~node_id:key ~ltr:loc_trace exn' | _ diff --git a/infer/src/backend/symExec.ml b/infer/src/backend/symExec.ml index ee0660e72..c4289eb52 100644 --- a/infer/src/backend/symExec.ml +++ b/infer/src/backend/symExec.ml @@ -1388,7 +1388,7 @@ and instrs ?(mask_errors= false) tenv pdesc instrs ppl = let loc = match ml_source with Some ml_loc -> "at " ^ L.ml_loc_to_string ml_loc | None -> "" in - L.d_warning ("Generated Instruction Failed with: " ^ Localise.to_issue_id err_name ^ loc) ; + L.d_warning ("Generated Instruction Failed with: " ^ err_name.IssueType.unique_id ^ loc) ; L.d_ln () ; [(p, path)] in diff --git a/infer/src/base/CommandLineOption.ml b/infer/src/base/CommandLineOption.ml index 08fa2cfa7..ee969bcfc 100644 --- a/infer/src/base/CommandLineOption.ml +++ b/infer/src/base/CommandLineOption.ml @@ -382,15 +382,17 @@ let reset_doc_opt ~long = Printf.sprintf "Cancel the effect of $(b,%s)." (dashda let reset_doc_list ~long = Printf.sprintf "Set $(b,%s) to the empty list." (dashdash long) -let mk_option ?(default= None) ?(default_to_string= fun _ -> "") ~f ?(deprecated= []) ~long ?short - ?parse_mode ?in_help ?(meta= "string") doc = +let mk_option ?(default= None) ?(default_to_string= fun _ -> "") ~f ?(mk_reset= true) + ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta= "string") doc = let mk () = mk ~deprecated ~long ?short ~default ?parse_mode ?in_help ~meta doc ~default_to_string ~decode_json:(string_json_decoder ~long) ~mk_setter:(fun var str -> var := f str) ~mk_spec: (fun set -> String set ) in - let reset_doc = reset_doc_opt ~long in - mk_with_reset None ~reset_doc ~long ?parse_mode mk + if mk_reset then + let reset_doc = reset_doc_opt ~long in + mk_with_reset None ~reset_doc ~long ?parse_mode mk + else mk () let mk_bool ?(deprecated_no= []) ?(default= false) ?(f= fun b -> b) ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta= "") doc = @@ -470,17 +472,18 @@ let mk_string ~default ?(f= fun s -> s) ?(deprecated= []) ~long ?short ?parse_mo ~default_to_string:(fun s -> s) ~mk_setter:(fun var str -> var := f str) ~decode_json:(string_json_decoder ~long) ~mk_spec:(fun set -> String set ) -let mk_string_opt ?default ?(f= fun s -> s) ?(deprecated= []) ~long ?short ?parse_mode ?in_help - ?(meta= "string") doc = +let mk_string_opt ?default ?(f= fun s -> s) ?mk_reset ?(deprecated= []) ~long ?short ?parse_mode + ?in_help ?(meta= "string") doc = let default_to_string = function Some s -> s | None -> "" in let f s = Some (f s) in - mk_option ~deprecated ~long ?short ~default ~default_to_string ~f ?parse_mode ?in_help ~meta doc + mk_option ~deprecated ~long ?short ~default ~default_to_string ~f ?mk_reset ?parse_mode ?in_help + ~meta doc let mk_string_list ?(default= []) ?(f= fun s -> s) ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?(meta= "string") doc = let mk () = mk ~deprecated ~long ?short ~default ?parse_mode ?in_help ~meta:("+" ^ meta) doc - ~default_to_string:(String.concat ~sep:", ") ~mk_setter:(fun var str -> var := f str :: !var) + ~default_to_string:(String.concat ~sep:",") ~mk_setter:(fun var str -> var := f str :: !var) ~decode_json:(list_json_decoder (string_json_decoder ~long)) ~mk_spec:(fun set -> String set ) in @@ -541,18 +544,19 @@ let mk_symbols_meta symbols = let strings = List.map ~f:fst symbols in Printf.sprintf "{ %s }" (String.concat ~sep:" | " strings) -let mk_symbol ~default ~symbols ~eq ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?meta doc = +let mk_symbol ~default ~symbols ~eq ?(f= Fn.id) ?(deprecated= []) ~long ?short ?parse_mode ?in_help + ?meta doc = let strings = List.map ~f:fst symbols in let sym_to_str = List.map ~f:(fun (x, y) -> (y, x)) symbols in let of_string str = List.Assoc.find_exn ~equal:String.equal symbols str in let to_string sym = List.Assoc.find_exn ~equal:eq sym_to_str sym in let meta = Option.value meta ~default:(mk_symbols_meta symbols) in mk ~deprecated ~long ?short ~default ?parse_mode ?in_help ~meta doc - ~default_to_string:(fun s -> to_string s) ~mk_setter:(fun var str -> var := of_string str) + ~default_to_string:(fun s -> to_string s) ~mk_setter:(fun var str -> var := of_string str |> f) ~decode_json:(string_json_decoder ~long) ~mk_spec:(fun set -> Symbol (strings, set) ) -let mk_symbol_opt ~symbols ?(f= Fn.id) ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?meta - doc = +let mk_symbol_opt ~symbols ?(f= Fn.id) ?(mk_reset= true) ?(deprecated= []) ~long ?short ?parse_mode + ?in_help ?meta doc = let strings = List.map ~f:fst symbols in let of_string str = List.Assoc.find_exn ~equal:String.equal symbols str in let meta = Option.value meta ~default:(mk_symbols_meta symbols) in @@ -561,8 +565,10 @@ let mk_symbol_opt ~symbols ?(f= Fn.id) ?(deprecated= []) ~long ?short ?parse_mod ~default_to_string:(fun _ -> "") ~mk_setter:(fun var str -> var := Some (f (of_string str))) ~decode_json:(string_json_decoder ~long) ~mk_spec:(fun set -> Symbol (strings, set) ) in - let reset_doc = reset_doc_opt ~long in - mk_with_reset None ~reset_doc ~long ?parse_mode mk + if mk_reset then + let reset_doc = reset_doc_opt ~long in + mk_with_reset None ~reset_doc ~long ?parse_mode mk + else mk () let mk_symbol_seq ?(default= []) ~symbols ~eq ?(deprecated= []) ~long ?short ?parse_mode ?in_help ?meta doc = @@ -794,7 +800,9 @@ let decode_inferconfig_to_argv path = let {decode_json} = List.find_exn ~f:(fun {long; short} -> - String.equal key long || (* for deprecated options *) String.equal key short) + String.equal key long || String.equal key short + (* for deprecated options *) + || (* for deprecated options that start with "-" *) String.equal ("-" ^ key) short) !desc_list in decode_json ~inferconfig_dir json_val @ result diff --git a/infer/src/base/CommandLineOption.mli b/infer/src/base/CommandLineOption.mli index 0a3bbb273..b6bb0911e 100644 --- a/infer/src/base/CommandLineOption.mli +++ b/infer/src/base/CommandLineOption.mli @@ -83,7 +83,7 @@ val mk_set : 'a ref -> 'a -> unit t val mk_option : ?default:'a option -> ?default_to_string:('a option -> string) -> f:(string -> 'a option) - -> 'a option ref t + -> ?mk_reset:bool -> 'a option ref t val mk_bool : ?deprecated_no:string list -> ?default:bool -> ?f:(bool -> bool) -> bool ref t (** [mk_bool long short doc] defines a [bool ref] set by the command line flag [--long] (and @@ -109,7 +109,10 @@ val mk_float_opt : ?default:float -> float option ref t val mk_string : default:string -> ?f:(string -> string) -> string ref t -val mk_string_opt : ?default:string -> ?f:(string -> string) -> string option ref t +val mk_string_opt : + ?default:string -> ?f:(string -> string) -> ?mk_reset:bool -> string option ref t +(** An option "--[long]-reset" is automatically created that resets the reference to None when found + on the command line, unless [mk_reset] is false. *) val mk_string_list : ?default:string list -> ?f:(string -> string) -> string list ref t (** [mk_string_list] defines a [string list ref], initialized to [[]] unless overridden by @@ -129,12 +132,14 @@ val mk_path_opt : ?default:string -> string option ref t val mk_path_list : ?default:string list -> string list ref t (** analogous of [mk_string_list] with the extra feature of [mk_path] *) -val mk_symbol : default:'a -> symbols:(string * 'a) list -> eq:('a -> 'a -> bool) -> 'a ref t +val mk_symbol : + default:'a -> symbols:(string * 'a) list -> eq:('a -> 'a -> bool) -> ?f:('a -> 'a) -> 'a ref t (** [mk_symbol long symbols] defines a command line flag [--long ] where [(,_)] is an element of [symbols]. *) -val mk_symbol_opt : symbols:(string * 'a) list -> ?f:('a -> 'a) -> 'a option ref t -(** [mk_symbol_opt] is similar to [mk_symbol] but defaults to [None]. *) +val mk_symbol_opt : + symbols:(string * 'a) list -> ?f:('a -> 'a) -> ?mk_reset:bool -> 'a option ref t +(** [mk_symbol_opt] is similar to [mk_symbol] but defaults to [None]. If [mk_reset] is false then do not create an additional --[long]-reset option to reset the value of the option to [None]. *) val mk_symbol_seq : ?default:'a list -> symbols:(string * 'a) list -> eq:('a -> 'a -> bool) -> 'a list ref t diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 52b196bf3..162ea3ee7 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -111,8 +111,6 @@ let buck_results_dir_name = "infer" let captured_dir_name = "captured" -let checks_disabled_by_default = ["GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL"] - let clang_initializer_prefix = "__infer_globals_initializer_" (** Experimental: if true do some specialized analysis of concurrent constructs. *) @@ -894,7 +892,7 @@ and ( bo_debug and filtering = CLOpt.mk_bool ~deprecated_no:["nf"] ~long:"filtering" ~short:'f' ~default:true ~in_help:CLOpt.([(Report, manual_generic)]) - "Do not show the results from experimental and blacklisted checks" + "Do not show the experimental and blacklisted issue types" and only_cheap_debug = CLOpt.mk_bool ~long:"only-cheap-debug" ~default:true "Disable expensive debugging output" and print_buckets = @@ -1023,26 +1021,31 @@ and differential_filter_set = ~symbols:[("introduced", `Introduced); ("fixed", `Fixed); ("preexisting", `Preexisting)] ~default:[`Introduced; `Fixed; `Preexisting] -and disable_checks = - CLOpt.mk_string_list ~deprecated:["disable_checks"] ~long:"disable-checks" ~meta:"error_name" - ~in_help:CLOpt.([(Report, manual_generic)]) - ~default: - [ "ANALYSIS_STOPS" - ; "ARRAY_OUT_OF_BOUNDS_L1" - ; "ARRAY_OUT_OF_BOUNDS_L2" - ; "ARRAY_OUT_OF_BOUNDS_L3" - ; "CLASS_CAST_EXCEPTION" - ; "CONDITION_ALWAYS_FALSE" - ; "CONDITION_ALWAYS_TRUE" - ; "DANGLING_POINTER_DEREFERENCE" - ; "DIVIDE_BY_ZERO" - ; "NULL_TEST_AFTER_DEREFERENCE" - ; "RETAIN_CYCLE" - ; "RETURN_VALUE_IGNORED" - ; "STACK_VARIABLE_ADDRESS_ESCAPE" - ; "UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" - ; "UNINITIALIZED_VALUE" ] - "Do not show reports coming from this type of errors. This option has lower precedence than $(b,--no-filtering) and $(b,--enable-checks)" +and () = + let mk b ?deprecated ~long ?default doc = + let _ : string list ref = + CLOpt.mk_string_list ?deprecated ~long + ~f:(fun issue_id -> + let issue = IssueType.from_string issue_id in + IssueType.set_enabled issue b ; issue_id) + ?default ~meta:"issue_type" + ~in_help:CLOpt.([(Report, manual_generic)]) + doc + in + () + in + let disabled_issues_ids = + IssueType.all_issues () + |> List.filter_map ~f:(fun issue -> + if not issue.IssueType.enabled then Some issue.IssueType.unique_id else None ) + in + mk false ~default:disabled_issues_ids ~long:"disable-issue-type" + ~deprecated:["disable_checks"; "-disable-checks"] + (Printf.sprintf + "Do not show reports coming from this type of issue. Each checker can report a range of issue types. This option provides fine-grained filtering over which types of issue should be reported once the checkers have run. In particular, note that disabling issue types does not make the corresponding checker not run.\n By default, the following issue types are disabled: %s.\n\n See also $(b,--report-issue-type).\n" + (String.concat ~sep:", " disabled_issues_ids)) ; + mk true ~long:"enable-issue-type" ~deprecated:["enable_checks"; "-enable-checks"] + "Show reports coming from this type of issue. By default, all issue types are enabled except the ones listed in $(b,--disable-issue-type). Note that enabling issue types does not make the corresponding checker run; see individual checker options to turn them on or off." and dotty_cfg_libs = CLOpt.mk_bool ~deprecated:["dotty_no_cfg_libs"] ~long:"dotty-cfg-libs" ~default:true @@ -1058,10 +1061,6 @@ and dynamic_dispatch = "Specify treatment of dynamic dispatch in Java code: 'none' treats dynamic dispatch as a call to unknown code, 'lazy' follows the JVM semantics and creates procedure descriptions during symbolic execution using the type information found in the abstract state; 'sound' is significantly more computationally expensive" ~symbols:[("none", `None); ("interface", `Interface); ("sound", `Sound); ("lazy", `Lazy)] -and enable_checks = - CLOpt.mk_string_list ~deprecated:["enable_checks"] ~long:"enable-checks" ~meta:"error_name" - "Show reports coming from this type of errors. This option has higher precedence than $(b,--disable-checks)" - and eradicate_condition_redundant = CLOpt.mk_bool ~long:"eradicate-condition-redundant" "Condition redundant warnings" @@ -1966,12 +1965,8 @@ and differential_filter_files = !differential_filter_files and differential_filter_set = !differential_filter_set -and disable_checks = !disable_checks - and dotty_cfg_libs = !dotty_cfg_libs -and enable_checks = !enable_checks - and eradicate = !eradicate and eradicate_condition_redundant = !eradicate_condition_redundant diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 9a5e41c7d..122a4900d 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -99,8 +99,6 @@ val buck_infer_deps_file_name : string val captured_dir_name : string -val checks_disabled_by_default : string list - val clang_initializer_prefix : string val classpath : string option @@ -358,16 +356,12 @@ val differential_filter_files : string option val differential_filter_set : [`Introduced | `Fixed | `Preexisting] list -val disable_checks : string list - val dotty_cfg_libs : bool val dump_duplicate_symbols : bool val dynamic_dispatch : [`None | `Interface | `Sound | `Lazy] -val enable_checks : string list - val eradicate : bool val eradicate_condition_redundant : bool diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml new file mode 100644 index 000000000..4a95c383a --- /dev/null +++ b/infer/src/base/IssueType.ml @@ -0,0 +1,271 @@ +(* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) +open! IStd + +(* Make sure we cannot create new issue types other than by calling [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; mutable enabled: bool; mutable hum: string} + [@@deriving compare] + + val equal : t -> t -> bool + + val from_string : ?enabled:bool -> ?hum:string -> string -> t + + val all_issues : unit -> t list + + val set_enabled : t -> bool -> unit +end = struct + module T = struct + type t = {unique_id: string; mutable enabled: bool; mutable hum: string} + + let compare {unique_id= id1} {unique_id= id2} = String.compare id1 id2 + + let equal = [%compare.equal : t] + end + + include T + module IssueSet = Caml.Set.Make (T) + + (** keep track of the list of all declared issue types *) + let all_issues = ref IssueSet.empty + + let prettify s = + String.lowercase s |> String.split ~on:'_' |> List.map ~f:String.capitalize + |> String.concat ~sep:" " |> String.strip + + let set_enabled issue b = issue.enabled <- b + + (** avoid creating new issue types. The idea is that there are three types of issue types: + 1. Statically pre-defined issue types, namely the ones in this module + + 2. Dynamically created ones, eg from custom errors defined in the models, or defined by the + user in AL linters + + 3. Issue types created at command-line-parsing time. These can mention issues of type 1. or + 2., but issues of type 2. have not yet been defined. Thus, we record only there [enabled] + status definitely. The [hum]an-readable description can be updated when we encounter the + definition of the issue type, eg in AL. *) + let from_string ?(enabled= true) ?hum:hum0 unique_id = + let hum = match hum0 with Some str -> str | _ -> prettify unique_id in + let issue = {unique_id; enabled; hum} in + try + let old = IssueSet.find issue !all_issues in + (* update human-readable string in case it was supplied this time, but keep the previous + value of enabled (see doc comment) *) + if Option.is_some hum0 then old.hum <- hum ; + old + with Not_found -> + all_issues := IssueSet.add issue !all_issues ; + issue + + let all_issues () = IssueSet.elements !all_issues +end + +include Unsafe + +(** pretty print a localised string *) +let pp fmt t = Format.fprintf fmt "%s" t.unique_id + +let abduction_case_not_implemented = from_string "Abduction_case_not_implemented" + +let analysis_stops = from_string ~enabled:false "ANALYSIS_STOPS" + +let array_of_pointsto = from_string "Array_of_pointsto" + +let array_out_of_bounds_l1 = from_string ~enabled:false "ARRAY_OUT_OF_BOUNDS_L1" + +let array_out_of_bounds_l2 = from_string ~enabled:false "ARRAY_OUT_OF_BOUNDS_L2" + +let array_out_of_bounds_l3 = from_string ~enabled:false "ARRAY_OUT_OF_BOUNDS_L3" + +let assert_failure = from_string "Assert_failure" + +let bad_footprint = from_string "Bad_footprint" + +let buffer_overrun = from_string "BUFFER_OVERRUN" + +let cannot_star = from_string "Cannot_star" + +let checkers_access_global = from_string "CHECKERS_ACCESS_GLOBAL" + +let checkers_immutable_cast = from_string "CHECKERS_IMMUTABLE_CAST" + +let checkers_print_c_call = from_string "CHECKERS_PRINT_C_CALL" + +let checkers_print_objc_method_calls = from_string "CHECKERS_PRINT_OBJC_METHOD_CALLS" + +let checkers_printf_args = from_string "CHECKERS_PRINTF_ARGS" + +let checkers_repeated_calls = from_string "CHECKERS_REPEATED_CALLS" + +let checkers_trace_calls_sequence = from_string "CHECKERS_TRACE_CALLS_SEQUENCE" + +let class_cast_exception = from_string ~enabled:false "CLASS_CAST_EXCEPTION" + +let cluster_callback = from_string "CLUSTER_CALLBACK" + +let codequery = from_string "Codequery" + +let comparing_floats_for_equality = from_string "COMPARING_FLOAT_FOR_EQUALITY" + +let condition_always_false = from_string ~enabled:false "CONDITION_ALWAYS_FALSE" + +let condition_always_true = from_string ~enabled:false "CONDITION_ALWAYS_TRUE" + +let context_leak = from_string "CONTEXT_LEAK" + +let dangling_pointer_dereference = from_string ~enabled:false "DANGLING_POINTER_DEREFERENCE" + +let dead_store = from_string "DEAD_STORE" + +let deallocate_stack_variable = from_string "DEALLOCATE_STACK_VARIABLE" + +let deallocate_static_memory = from_string "DEALLOCATE_STATIC_MEMORY" + +let deallocation_mismatch = from_string "DEALLOCATION_MISMATCH" + +let divide_by_zero = from_string ~enabled:false "DIVIDE_BY_ZERO" + +let double_lock = from_string "DOUBLE_LOCK" + +let empty_vector_access = from_string "EMPTY_VECTOR_ACCESS" + +let eradicate_condition_redundant = + from_string "ERADICATE_CONDITION_REDUNDANT" ~hum:"Condition Redundant" + +let eradicate_condition_redundant_nonnull = + from_string "ERADICATE_CONDITION_REDUNDANT_NONNULL" ~hum:"Condition Redundant Non-Null" + +let eradicate_field_not_initialized = + from_string "ERADICATE_FIELD_NOT_INITIALIZED" ~hum:"Field Not Initialized" + +let eradicate_field_not_mutable = + from_string "ERADICATE_FIELD_NOT_MUTABLE" ~hum:"Field Not Mutable" + +let eradicate_field_not_nullable = + from_string "ERADICATE_FIELD_NOT_NULLABLE" ~hum:"Field Not Nullable" + +let eradicate_field_over_annotated = + from_string "ERADICATE_FIELD_OVER_ANNOTATED" ~hum:"Field Over Annotated" + +let eradicate_field_value_absent = + from_string "ERADICATE_FIELD_VALUE_ABSENT" ~hum:"Field Value Absent" + +let eradicate_inconsistent_subclass_parameter_annotation = + from_string "ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION" + ~hum:"Inconsistent Subclass Parameter Annotation" + +let eradicate_inconsistent_subclass_return_annotation = + from_string "ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION" + ~hum:"Inconsistent Subclass Return Annotation" + +let eradicate_null_field_access = + from_string "ERADICATE_NULL_FIELD_ACCESS" ~hum:"Null Field Access" + +let eradicate_null_method_call = from_string "ERADICATE_NULL_METHOD_CALL" ~hum:"Null Method Call" + +let eradicate_parameter_not_nullable = + from_string "ERADICATE_PARAMETER_NOT_NULLABLE" ~hum:"Parameter Not Nullable" + +let eradicate_parameter_value_absent = + from_string "ERADICATE_PARAMETER_VALUE_ABSENT" ~hum:"Parameter Value Absent" + +let eradicate_return_not_nullable = + from_string "ERADICATE_RETURN_NOT_NULLABLE" ~hum:"Return Not Nullable" + +let eradicate_return_over_annotated = + from_string "ERADICATE_RETURN_OVER_ANNOTATED" ~hum:"Return Over Annotated" + +let eradicate_return_value_not_present = + from_string "ERADICATE_RETURN_VALUE_NOT_PRESENT" ~hum:"Return Value Not Present" + +let eradicate_value_not_present = + from_string "ERADICATE_VALUE_NOT_PRESENT" ~hum:"Value Not Present" + +let failure_exe = from_string "Failure_exe" + +let field_should_be_nullable = from_string "FIELD_SHOULD_BE_NULLABLE" + +let field_not_null_checked = from_string "IVAR_NOT_NULL_CHECKED" + +(* from AL default linters *) +let _global_variable_initialized_with_function_or_method_call = + from_string ~enabled:false "GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL" + +let inherently_dangerous_function = from_string "INHERENTLY_DANGEROUS_FUNCTION" + +let internal_error = from_string "Internal_error" + +let leak_after_array_abstraction = from_string "Leak_after_array_abstraction" + +let leak_in_footprint = from_string "Leak_in_footprint" + +let memory_leak = from_string "MEMORY_LEAK" + +let missing_fld = from_string "Missing_fld" ~hum:"Missing Field" + +let null_dereference = from_string "NULL_DEREFERENCE" + +let null_test_after_dereference = from_string ~enabled:false "NULL_TEST_AFTER_DEREFERENCE" + +let parameter_not_null_checked = from_string "PARAMETER_NOT_NULL_CHECKED" + +let pointer_size_mismatch = from_string "POINTER_SIZE_MISMATCH" + +let precondition_not_found = from_string "PRECONDITION_NOT_FOUND" + +let precondition_not_met = from_string "PRECONDITION_NOT_MET" + +let premature_nil_termination = from_string "PREMATURE_NIL_TERMINATION_ARGUMENT" + +let proc_callback = from_string "PROC_CALLBACK" ~hum:"Procedure Callback" + +let quandary_taint_error = from_string "QUANDARY_TAINT_ERROR" + +let registered_observer_being_deallocated = from_string "REGISTERED_OBSERVER_BEING_DEALLOCATED" + +let resource_leak = from_string "RESOURCE_LEAK" + +let retain_cycle = from_string ~enabled:false "RETAIN_CYCLE" + +let return_expression_required = from_string "RETURN_EXPRESSION_REQUIRED" + +let return_statement_missing = from_string "RETURN_STATEMENT_MISSING" + +let return_value_ignored = from_string ~enabled:false "RETURN_VALUE_IGNORED" + +let skip_function = from_string "SKIP_FUNCTION" + +let skip_pointer_dereference = from_string "SKIP_POINTER_DEREFERENCE" + +let stack_variable_address_escape = from_string ~enabled:false "STACK_VARIABLE_ADDRESS_ESCAPE" + +let static_initialization_order_fiasco = from_string "STATIC_INITIALIZATION_ORDER_FIASCO" + +let symexec_memory_error = + from_string "Symexec_memory_error" ~hum:"Symbolic Execution Memory Error" + +let thread_safety_violation = from_string "THREAD_SAFETY_VIOLATION" + +let unary_minus_applied_to_unsigned_expression = + from_string ~enabled:false "UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" + +let uninitialized_value = from_string ~enabled:false "UNINITIALIZED_VALUE" + +let unknown_proc = from_string "Unknown_proc" ~hum:"Unknown Procedure" + +let unreachable_code_after = from_string "UNREACHABLE_CODE" + +let unsafe_guarded_by_access = from_string "UNSAFE_GUARDED_BY_ACCESS" + +let use_after_free = from_string "USE_AFTER_FREE" + +let wrong_argument_number = from_string "Wrong_argument_number" ~hum:"Wrong Argument Number" diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli new file mode 100644 index 000000000..fe71adace --- /dev/null +++ b/infer/src/base/IssueType.mli @@ -0,0 +1,200 @@ +(* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) + +open! IStd + +(** type of string used for localisation *) +type t = private + {unique_id: string; mutable enabled: bool; mutable hum: string} + [@@deriving compare] + +val equal : t -> t -> bool + +val all_issues : unit -> t list +(** all the issues declared so far *) + +val pp : Format.formatter -> t -> unit +(** pretty print a localised string *) + +val from_string : ?enabled:bool -> ?hum:string -> string -> t +(** create from an ordinary string *) + +val set_enabled : t -> bool -> unit + +val abduction_case_not_implemented : t + +val analysis_stops : t + +val array_of_pointsto : t + +val array_out_of_bounds_l1 : t + +val array_out_of_bounds_l2 : t + +val array_out_of_bounds_l3 : t + +val assert_failure : t + +val bad_footprint : t + +val buffer_overrun : t + +val cannot_star : t + +val checkers_access_global : t + +val checkers_immutable_cast : t + +val checkers_print_c_call : t + +val checkers_print_objc_method_calls : t + +val checkers_printf_args : t + +val checkers_repeated_calls : t + +val checkers_trace_calls_sequence : t + +val class_cast_exception : t + +val cluster_callback : t + +val codequery : t + +val comparing_floats_for_equality : t + +val condition_always_false : t + +val condition_always_true : t + +val context_leak : t + +val dangling_pointer_dereference : t + +val dead_store : t + +val deallocate_stack_variable : t + +val deallocate_static_memory : t + +val deallocation_mismatch : t + +val divide_by_zero : t + +val double_lock : t + +val empty_vector_access : t + +val eradicate_condition_redundant : t + +val eradicate_condition_redundant_nonnull : t + +val eradicate_field_not_initialized : t + +val eradicate_field_not_mutable : t + +val eradicate_field_not_nullable : t + +val eradicate_field_over_annotated : t + +val eradicate_field_value_absent : t + +val eradicate_inconsistent_subclass_parameter_annotation : t + +val eradicate_inconsistent_subclass_return_annotation : t + +val eradicate_null_field_access : t + +val eradicate_null_method_call : t + +val eradicate_parameter_not_nullable : t + +val eradicate_parameter_value_absent : t + +val eradicate_return_not_nullable : t + +val eradicate_return_over_annotated : t + +val eradicate_return_value_not_present : t + +val eradicate_value_not_present : t + +val failure_exe : t + +val field_should_be_nullable : t + +val field_not_null_checked : t + +val inherently_dangerous_function : t + +val internal_error : t + +val leak_after_array_abstraction : t + +val leak_in_footprint : t + +val memory_leak : t + +val missing_fld : t + +val null_dereference : t + +val null_test_after_dereference : t + +val parameter_not_null_checked : t + +val pointer_size_mismatch : t + +val precondition_not_found : t + +val precondition_not_met : t + +val premature_nil_termination : t + +val proc_callback : t + +val quandary_taint_error : t + +val registered_observer_being_deallocated : t + +val resource_leak : t + +val retain_cycle : t + +val return_expression_required : t + +val return_statement_missing : t + +val return_value_ignored : t + +val skip_function : t + +val skip_pointer_dereference : t + +val stack_variable_address_escape : t + +val static_initialization_order_fiasco : t + +val symexec_memory_error : t + +val thread_safety_violation : t + +val unary_minus_applied_to_unsigned_expression : t + +val uninitialized_value : t + +val unknown_proc : t + +val unreachable_code_after : t + +val unsafe_guarded_by_access : t + +val use_after_free : t + +val wrong_argument_number : t diff --git a/infer/src/bufferoverrun/bufferOverrunChecker.ml b/infer/src/bufferoverrun/bufferOverrunChecker.ml index 25d2aab72..cb8c38ca0 100644 --- a/infer/src/bufferoverrun/bufferOverrunChecker.ml +++ b/infer/src/bufferoverrun/bufferOverrunChecker.ml @@ -576,9 +576,7 @@ module Report = struct | Some bucket when Typ.Procname.equal pname caller_pname -> let description = Dom.Condition.to_string cond in let error_desc = Localise.desc_buffer_overrun bucket description in - let exn = - Exceptions.Checkers (Localise.to_issue_id Localise.buffer_overrun, error_desc) - in + let exn = Exceptions.Checkers (IssueType.buffer_overrun.unique_id, error_desc) in let trace = match TraceSet.choose_shortest cond.Dom.Condition.traces with | trace diff --git a/infer/src/checkers/NullabilitySuggest.ml b/infer/src/checkers/NullabilitySuggest.ml index f23b88c27..64f7f1e12 100644 --- a/infer/src/checkers/NullabilitySuggest.ml +++ b/infer/src/checkers/NullabilitySuggest.ml @@ -147,7 +147,7 @@ let pretty_field_name proc_data field_name = let checker {Callbacks.summary; proc_desc; tenv} = let report astate (proc_data: extras ProcData.t) = let report_access_path ap udchain = - let issue_kind = Localise.to_issue_id Localise.field_should_be_nullable in + let issue_kind = IssueType.field_should_be_nullable.unique_id in match AccessPath.get_field_and_annotation ap proc_data.tenv with | Some (field_name, _) when Typ.Fieldname.Java.is_captured_parameter field_name -> (* Skip reporting when field comes from generated code *) diff --git a/infer/src/checkers/Siof.ml b/infer/src/checkers/Siof.ml index 2f868070b..3c60d9293 100644 --- a/infer/src/checkers/Siof.ml +++ b/infer/src/checkers/Siof.ml @@ -219,7 +219,7 @@ let report_siof summary trace pdesc gname loc = (description, (passthroughs, (final_sink', pt) :: rest)) in let ltr = SiofTrace.trace_of_error loc gname sink_path' in - let msg = Localise.to_issue_id Localise.static_initialization_order_fiasco in + let msg = IssueType.static_initialization_order_fiasco.unique_id in let exn = Exceptions.Checkers (msg, Localise.verbatim_desc description) in Reporting.log_error summary ~loc ~ltr exn in diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index 9dfa412ca..b1caf9a48 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -1185,7 +1185,7 @@ let report_thread_safety_violation tenv pdesc ~make_description ~conflicts acces let final_sink_site = PathDomain.Sink.call_site final_sink in let loc = CallSite.loc initial_sink_site in let ltr = make_trace_with_conflicts conflicts path pdesc in - let msg = Localise.to_issue_id Localise.thread_safety_violation in + let msg = IssueType.thread_safety_violation.unique_id in let description = make_description tenv pname final_sink_site initial_sink_site final_sink in let exn = Exceptions.Checkers (msg, Localise.verbatim_desc description) in Reporting.log_error_deprecated ~store_summary:true pname ~loc ~ltr exn diff --git a/infer/src/checkers/immutableChecker.ml b/infer/src/checkers/immutableChecker.ml index 42141ddf4..519e63ae5 100644 --- a/infer/src/checkers/immutableChecker.ml +++ b/infer/src/checkers/immutableChecker.ml @@ -38,7 +38,7 @@ let check_immutable_cast tenv curr_pname curr_pdesc typ_expected typ_found_opt l (Typ.Procname.to_simplified_string curr_pname) Typ.Name.pp name_given Typ.Name.pp name_expected in - Checkers.ST.report_error tenv curr_pname curr_pdesc Localise.checkers_immutable_cast + Checkers.ST.report_error tenv curr_pname curr_pdesc IssueType.checkers_immutable_cast loc description | _ -> () ) diff --git a/infer/src/checkers/liveness.ml b/infer/src/checkers/liveness.ml index 4b3180723..79a0598f5 100644 --- a/infer/src/checkers/liveness.ml +++ b/infer/src/checkers/liveness.ml @@ -82,7 +82,7 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = when not ( Pvar.is_frontend_tmp pvar || Pvar.is_return pvar || Pvar.is_global pvar || Domain.mem (Var.of_pvar pvar) live_vars || is_captured_var pvar ) - -> let issue_id = Localise.to_issue_id Localise.dead_store in + -> let issue_id = IssueType.dead_store.unique_id in let message = F.asprintf "The value written to %a is never used" (Pvar.pp Pp.text) pvar in let ltr = [Errlog.make_trace_element 0 loc "Write of unused value" []] in let exn = Exceptions.Checkers (issue_id, Localise.verbatim_desc message) in diff --git a/infer/src/checkers/printfArgs.ml b/infer/src/checkers/printfArgs.ml index 0efe49561..b00eb26a9 100644 --- a/infer/src/checkers/printfArgs.ml +++ b/infer/src/checkers/printfArgs.ml @@ -172,11 +172,11 @@ let check_printf_args_ok tenv (node: Procdesc.Node.t) (instr: Sil.instr) -> check_type_names cl (printf.format_pos + 1) pn (format_string_type_names fmt 0) (fixed_nvar_type_names @ vararg_ivar_type_names) | None - -> Checkers.ST.report_error tenv proc_name proc_desc Localise.checkers_printf_args cl + -> Checkers.ST.report_error tenv proc_name proc_desc IssueType.checkers_printf_args cl "Format string must be string literal" with e -> L.internal_error "%s Exception when analyzing %s: %s@." - (Localise.to_issue_id Localise.checkers_printf_args) (Typ.Procname.to_string proc_name) + IssueType.checkers_printf_args.unique_id (Typ.Procname.to_string proc_name) (Exn.to_string e) ) | None -> () ) diff --git a/infer/src/checkers/repeatedCallsChecker.ml b/infer/src/checkers/repeatedCallsChecker.ml index 565bc1d22..c2b241efd 100644 --- a/infer/src/checkers/repeatedCallsChecker.ml +++ b/infer/src/checkers/repeatedCallsChecker.ml @@ -133,7 +133,7 @@ module RepeatedCallsExtension : Eradicate.ExtensionT = struct SourceFile.pp alloc_loc.Location.file alloc_loc.Location.line in Checkers.ST.report_error tenv curr_pname curr_pdesc - Localise.checkers_repeated_calls loc description + IssueType.checkers_repeated_calls loc description | None -> () ) | _ diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index 859229f36..ecb3d02d4 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -411,7 +411,7 @@ let get_err_log translation_unit_context method_decl_opt = in LintIssues.get_err_log procname -(* Add a frontend warning with a description desc at location loc to the errlog of a proc desc *) +(** Add a frontend warning with a description desc at location loc to the errlog of a proc desc *) let log_frontend_issue translation_unit_context method_decl_opt key (issue_desc: CIssue.issue_desc) linters_def_file = let errlog = get_err_log translation_unit_context method_decl_opt in diff --git a/infer/src/eradicate/typeErr.ml b/infer/src/eradicate/typeErr.ml index 6ccf5f4fb..0cc84f10b 100644 --- a/infer/src/eradicate/typeErr.ml +++ b/infer/src/eradicate/typeErr.ml @@ -260,7 +260,7 @@ end (* Strict *) type st_report_error = - Typ.Procname.t -> Procdesc.t -> Localise.t -> Location.t -> ?advice:string option + Typ.Procname.t -> Procdesc.t -> IssueType.t -> Location.t -> ?advice:string option -> ?field_name:Typ.Fieldname.t option -> ?origin_loc:Location.t option -> ?exception_kind:(string -> Localise.error_desc -> exn) -> ?always_report:bool -> string -> unit @@ -277,14 +277,14 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd | _ -> Typ.Procname.to_simplified_string pname in - L.progress "%s %s in %s %s@." ew_string (Localise.to_issue_id kind) mname s + L.progress "%s %s in %s %s@." ew_string kind.IssueType.unique_id mname s in let is_err, kind, description, advice, field_name, origin_loc = match err_instance with | Condition_redundant (b, s_opt, nonnull) -> let name = - if nonnull then Localise.eradicate_condition_redundant_nonnull - else Localise.eradicate_condition_redundant + if nonnull then IssueType.eradicate_condition_redundant_nonnull + else IssueType.eradicate_condition_redundant in ( false , name @@ -306,7 +306,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> MF.monospaced_to_string (Typ.Procname.to_simplified_string pn) in ( true - , Localise.eradicate_field_not_initialized + , IssueType.eradicate_field_not_initialized , Format.asprintf "Field %a is not initialized in %s and is not declared %a" MF.pp_monospaced (Typ.Fieldname.to_simplified_string fn) constructor_name MF.pp_monospaced "@Nullable" @@ -315,7 +315,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd , None ) | Field_not_mutable (fn, (origin_description, origin_loc, _)) -> ( true - , Localise.eradicate_field_not_mutable + , IssueType.eradicate_field_not_mutable , Format.asprintf "Field %a is modified but is not declared %a. %s" MF.pp_monospaced (Typ.Fieldname.to_simplified_string fn) MF.pp_monospaced "@Mutable" origin_description , None @@ -325,12 +325,12 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> let kind_s, description = match ann with | AnnotatedSignature.Nullable - -> ( Localise.eradicate_field_not_nullable + -> ( IssueType.eradicate_field_not_nullable , Format.asprintf "Field %a can be null but is not declared %a. %s" MF.pp_monospaced (Typ.Fieldname.to_simplified_string fn) MF.pp_monospaced "@Nullable" origin_description ) | AnnotatedSignature.Present - -> ( Localise.eradicate_field_value_absent + -> ( IssueType.eradicate_field_value_absent , Format.asprintf "Field %a is assigned a possibly absent value but is declared %a. %s" MF.pp_monospaced (Typ.Fieldname.to_simplified_string fn) MF.pp_monospaced @@ -348,7 +348,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> Typ.Procname.to_simplified_string pn in ( true - , Localise.eradicate_field_over_annotated + , IssueType.eradicate_field_over_annotated , Format.asprintf "Field %a is always initialized in %s but is declared %a" MF.pp_monospaced (Typ.Fieldname.to_simplified_string fn) constructor_name MF.pp_monospaced "@Nullable" @@ -358,7 +358,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd | Null_field_access (s_opt, fn, (origin_description, origin_loc, _), indexed) -> let at_index = if indexed then "element at index" else "field" in ( true - , Localise.eradicate_null_field_access + , IssueType.eradicate_null_field_access , Format.asprintf "Object %a could be null when accessing %s %a. %s" MF.pp_monospaced (Option.value s_opt ~default:"") at_index MF.pp_monospaced (Typ.Fieldname.to_simplified_string fn) origin_description @@ -369,12 +369,12 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> let kind_s, description = match ann with | AnnotatedSignature.Nullable - -> ( Localise.eradicate_null_method_call + -> ( IssueType.eradicate_null_method_call , Format.asprintf "The value of %a in the call to %a could be null. %s" MF.pp_monospaced (Option.value s_opt ~default:"") MF.pp_monospaced (Typ.Procname.to_simplified_string pn) origin_description ) | AnnotatedSignature.Present - -> ( Localise.eradicate_value_not_present + -> ( IssueType.eradicate_value_not_present , Format.asprintf "The value of %a in the call to %a is not %a. %s" MF.pp_monospaced (Option.value s_opt ~default:"") MF.pp_monospaced (Typ.Procname.to_simplified_string pn) MF.pp_monospaced "@Present" @@ -385,13 +385,13 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> let kind_s, description = match ann with | AnnotatedSignature.Nullable - -> ( Localise.eradicate_parameter_not_nullable + -> ( IssueType.eradicate_parameter_not_nullable , Format.asprintf "%a needs a non-null value in parameter %d but argument %a can be null. %s" MF.pp_monospaced (Typ.Procname.to_simplified_string pn) n MF.pp_monospaced s origin_desc ) | AnnotatedSignature.Present - -> ( Localise.eradicate_parameter_value_absent + -> ( IssueType.eradicate_parameter_value_absent , Format.asprintf "%a needs a present value in parameter %d but argument %a can be absent. %s" MF.pp_monospaced (Typ.Procname.to_simplified_string pn) n MF.pp_monospaced s @@ -402,12 +402,12 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> let kind_s, description = match ann with | AnnotatedSignature.Nullable - -> ( Localise.eradicate_return_not_nullable + -> ( IssueType.eradicate_return_not_nullable , Format.asprintf "Method %a may return null but it is not annotated with %a. %s" MF.pp_monospaced (Typ.Procname.to_simplified_string pn) MF.pp_monospaced "@Nullable" origin_description ) | AnnotatedSignature.Present - -> ( Localise.eradicate_return_value_not_present + -> ( IssueType.eradicate_return_value_not_present , Format.asprintf "Method %a may return an absent value but it is annotated with %a. %s" MF.pp_monospaced (Typ.Procname.to_simplified_string pn) MF.pp_monospaced @@ -416,7 +416,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd (true, kind_s, description, None, None, origin_loc) | Return_over_annotated pn -> ( false - , Localise.eradicate_return_over_annotated + , IssueType.eradicate_return_over_annotated , Format.asprintf "Method %a is annotated with %a but never returns null." MF.pp_monospaced (Typ.Procname.to_simplified_string pn) MF.pp_monospaced "@Nullable" , None @@ -424,7 +424,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd , None ) | Inconsistent_subclass_return_annotation (pn, opn) -> ( false - , Localise.eradicate_inconsistent_subclass_return_annotation + , IssueType.eradicate_inconsistent_subclass_return_annotation , Format.asprintf "Method %a is annotated with %a but overrides unannotated method %a." MF.pp_monospaced (Typ.Procname.to_simplified_string ~withclass:true pn) MF.pp_monospaced "@Nullable" MF.pp_monospaced @@ -444,7 +444,7 @@ let report_error_now tenv (st_report_error: st_report_error) err_instance loc pd -> string_of_int n ^ "th" in ( false - , Localise.eradicate_inconsistent_subclass_parameter_annotation + , IssueType.eradicate_inconsistent_subclass_parameter_annotation , Format.asprintf "%s parameter %a of method %a is not %a but is declared %ain the parent class method %a." (translate_position pos) MF.pp_monospaced param_name MF.pp_monospaced diff --git a/infer/src/eradicate/typeErr.mli b/infer/src/eradicate/typeErr.mli index a24b4f949..13aaf4c4c 100644 --- a/infer/src/eradicate/typeErr.mli +++ b/infer/src/eradicate/typeErr.mli @@ -73,7 +73,7 @@ type err_instance = val node_reset_forall : Procdesc.Node.t -> unit type st_report_error = - Typ.Procname.t -> Procdesc.t -> Localise.t -> Location.t -> ?advice:string option + Typ.Procname.t -> Procdesc.t -> IssueType.t -> Location.t -> ?advice:string option -> ?field_name:Typ.Fieldname.t option -> ?origin_loc:Location.t option -> ?exception_kind:(string -> Localise.error_desc -> exn) -> ?always_report:bool -> string -> unit diff --git a/infer/src/labs/ResourceLeaks.ml b/infer/src/labs/ResourceLeaks.ml index 9b4234f30..b0327ded8 100644 --- a/infer/src/labs/ResourceLeaks.ml +++ b/infer/src/labs/ResourceLeaks.ml @@ -104,7 +104,7 @@ let checker {Callbacks.summary; proc_desc; tenv} : Specs.summary = let report leak_count (proc_data: extras ProcData.t) = if leak_count > 0 (* 2(a) *) then let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in - let issue_kind = Localise.to_issue_id Localise.resource_leak in + let issue_kind = IssueType.resource_leak.unique_id in let message = F.asprintf "Leaked %d resource(s)" leak_count in let exn = Exceptions.Checkers (issue_kind, Localise.verbatim_desc message) in Reporting.log_error summary ~loc:last_loc exn diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index a945467da..f7451be88 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -225,7 +225,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct Errlog.make_trace_element 0 (CallSite.loc call_site) desc []) expanded_sinks in - let msg = Localise.to_issue_id Localise.quandary_taint_error in + let msg = IssueType.quandary_taint_error.unique_id in let _, original_source = List.hd_exn expanded_sources in let final_sink = List.hd_exn expanded_sinks in let trace_str = get_short_trace_string original_source final_sink in diff --git a/infer/src/unit/DifferentialFiltersTests.ml b/infer/src/unit/DifferentialFiltersTests.ml index 7e5efbb17..f7c126b66 100644 --- a/infer/src/unit/DifferentialFiltersTests.ml +++ b/infer/src/unit/DifferentialFiltersTests.ml @@ -325,8 +325,8 @@ let test_skip_anonymous_class_renamings = let test_interesting_paths_filter = let report = [ create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_1.java" ~hash:1 () - ; create_fake_jsonbug ~bug_type:(Localise.to_issue_id Localise.null_dereference) - ~file:"file_2.java" ~hash:2 () + ; create_fake_jsonbug ~bug_type:IssueType.null_dereference.unique_id ~file:"file_2.java" + ~hash:2 () ; create_fake_jsonbug ~bug_type:"bug_type_1" ~file:"file_4.java" ~hash:4 () ] in let create_test interesting_paths expected_hashes _ = diff --git a/infer/tests/codetoanalyze/java/.inferconfig b/infer/tests/codetoanalyze/java/.inferconfig index 5bd033efa..6d1e0898c 100644 --- a/infer/tests/codetoanalyze/java/.inferconfig +++ b/infer/tests/codetoanalyze/java/.inferconfig @@ -13,7 +13,7 @@ "infer-blacklist-files-containing": [ "@generated" ], - "enable-checks": [ + "enable-issue-type": [ "GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL" ], "skip-translation": [ diff --git a/infer/tests/codetoanalyze/java/quandary/issues.exp b/infer/tests/codetoanalyze/java/quandary/issues.exp index 84c4cd452..c6d02d342 100644 --- a/infer/tests/codetoanalyze/java/quandary/issues.exp +++ b/infer/tests/codetoanalyze/java/quandary/issues.exp @@ -44,13 +44,13 @@ codetoanalyze/java/quandary/ContentProviders.java, int ContentProviders.update(U codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.FP_propagateViaConcreteTypeOk(), 4, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data &return,Return from Object DynamicDispatch$BadSubtype.returnSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.FP_propagateViaConcreteTypeOk(), 7, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void DynamicDispatch$BadSubtype.callSink(Object),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.FP_propagateViaConcreteTypeOk(), 10, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] -codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.callSinkViaInterfaceBad(DynamicDispatch$Interface), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void DynamicDispatch$BadInterfaceImpl2.callSink(Object),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.callSinkViaInterfaceBad(DynamicDispatch$Interface), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void DynamicDispatch$BadInterfaceImpl1.callSink(Object),Call to void InferTaint.inferSensitiveSink(Object)] +codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.callSinkViaInterfaceBad(DynamicDispatch$Interface), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void DynamicDispatch$BadInterfaceImpl2.callSink(Object),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.callSinkViaSubtypeBad(DynamicDispatch$Supertype), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void DynamicDispatch$BadSubtype.callSink(Object),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.propagateViaInterfaceBad(DynamicDispatch$Interface), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.propagateViaSubtypeBad(DynamicDispatch$Supertype), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] -codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.returnSourceViaInterfaceBad(DynamicDispatch$Interface), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data &return,Return from Object DynamicDispatch$BadInterfaceImpl2.returnSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.returnSourceViaInterfaceBad(DynamicDispatch$Interface), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data &return,Return from Object DynamicDispatch$BadInterfaceImpl1.returnSource(),Call to void InferTaint.inferSensitiveSink(Object)] +codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.returnSourceViaInterfaceBad(DynamicDispatch$Interface), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data &return,Return from Object DynamicDispatch$BadInterfaceImpl2.returnSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/DynamicDispatch.java, void DynamicDispatch.returnSourceViaSubtypeBad(DynamicDispatch$Supertype), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource() with tainted data &return,Return from Object DynamicDispatch$BadSubtype.returnSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Exceptions.java, void Exceptions.callSinkThenThrowBad(), 1, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Exceptions.callSinkThenThrow(Object),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Exceptions.java, void Exceptions.sinkAfterCatchBad(), 7, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] @@ -152,44 +152,44 @@ codetoanalyze/java/quandary/Interprocedural.java, void Interprocedural.returnSou codetoanalyze/java/quandary/Interprocedural.java, void Interprocedural.returnSourceViaParameter2Bad(Interprocedural$Obj,Interprocedural$Obj), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Interprocedural.java, void Interprocedural.setGlobalThenCallSinkBad(), 2, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Interprocedural.callSinkOnGlobal(),Call to void InferTaint.inferSensitiveSink(Object)] codetoanalyze/java/quandary/Interprocedural.java, void Interprocedural.singlePassthroughBad(), 3, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void InferTaint.inferSensitiveSink(Object)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.e(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.e(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from double Location.getAltitude(),Call to int Log.e(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.e(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.e(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.e(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.e(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from float Location.getSpeed(),Call to int Log.e(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from float Location.getBearing(),Call to int Log.e(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.e(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.e(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.e(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.e(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.println(int,String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from double Location.getAltitude(),Call to int Log.println(int,String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.e(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from float Location.getBearing(),Call to int Log.e(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 36, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.e(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.println(int,String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from float Location.getSpeed(),Call to int Log.println(int,String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.println(int,String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.println(int,String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.println(int,String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.println(int,String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.println(int,String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from float Location.getBearing(),Call to int Log.println(int,String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.println(int,String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.println(int,String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from double Location.getAltitude(),Call to int Log.println(int,String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 37, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.println(int,String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.w(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.w(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.w(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from float Location.getBearing(),Call to int Log.w(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.w(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from float Location.getSpeed(),Call to int Log.w(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.w(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.w(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from double Location.getAltitude(),Call to int Log.w(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from float Location.getBearing(),Call to int Log.w(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.w(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.w(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.w(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.w(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.wtf(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from float Location.getSpeed(),Call to int Log.w(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 38, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.w(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getLine1Number(),Call to int Log.wtf(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from double Location.getAltitude(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSubscriberId(),Call to int Log.wtf(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.wtf(String,String)] -codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.wtf(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getDeviceId(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getSimSerialNumber(),Call to int Log.wtf(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from String TelephonyManager.getVoiceMailNumber(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from float Location.getBearing(),Call to int Log.wtf(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from double Location.getLatitude(),Call to int Log.wtf(String,String)] +codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from double Location.getAltitude(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from float Location.getSpeed(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [Return from double Location.getLongitude(),Call to int Log.wtf(String,String)] codetoanalyze/java/quandary/Recursion.java, void Recursion.callSinkThenDivergeBad(), 1, QUANDARY_TAINT_ERROR, [Return from Object InferTaint.inferSecretSource(),Call to void Recursion.callSinkThenDiverge(Object),Call to void InferTaint.inferSensitiveSink(Object)] diff --git a/infer/tests/codetoanalyze/objcpp/linters/Makefile b/infer/tests/codetoanalyze/objcpp/linters/Makefile index eff1f903a..1e42f19b4 100644 --- a/infer/tests/codetoanalyze/objcpp/linters/Makefile +++ b/infer/tests/codetoanalyze/objcpp/linters/Makefile @@ -10,7 +10,7 @@ TESTS_DIR = ../../.. ANALYZER = linters CLANG_OPTIONS = -x objective-c++ -std=c++11 -fobjc-arc -c INFER_OPTIONS = --no-filtering --debug-exceptions --project-root $(TESTS_DIR) --no-keep-going \ ---enable-checks GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL +--enable-issue-type GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL INFERPRINT_OPTIONS = --issues-tests SOURCES = \