diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index 3dd6065d2..4443953f1 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -358,6 +358,11 @@ OPTIONS Abduction_case_not_implemented (enabled by default), Array_of_pointsto (enabled by default), Assert_failure (enabled by default), + BIABD_CONDITION_ALWAYS_FALSE (disabled by default), + BIABD_CONDITION_ALWAYS_TRUE (disabled by default), + BIABD_REGISTERED_OBSERVER_BEING_DEALLOCATED (enabled by + default), + BIABD_STACK_VARIABLE_ADDRESS_ESCAPE (disabled by default), BIABD_USE_AFTER_FREE (enabled by default), BUFFER_OVERRUN_L1 (enabled by default), BUFFER_OVERRUN_L2 (enabled by default), @@ -455,6 +460,7 @@ OPTIONS IVAR_NOT_NULL_CHECKED (enabled by default), Internal_error (enabled by default), JAVASCRIPT_INJECTION (enabled by default), + LAB_RESOURCE_LEAK (enabled by default), LOCKLESS_VIOLATION (enabled by default), LOCK_CONSISTENCY_VIOLATION (enabled by default), LOGGING_PRIVATE_DATA (enabled by default), @@ -477,7 +483,6 @@ OPTIONS PULSE_MEMORY_LEAK (disabled by default), PURE_FUNCTION (enabled by default), QUANDARY_TAINT_ERROR (enabled by default), - REGISTERED_OBSERVER_BEING_DEALLOCATED (enabled by default), RESOURCE_LEAK (enabled by default), RETAIN_CYCLE (enabled by default), SHELL_INJECTION (enabled by default), @@ -486,7 +491,7 @@ OPTIONS SKIP_POINTER_DEREFERENCE (disabled by default), SQL_INJECTION (enabled by default), SQL_INJECTION_RISK (enabled by default), - STACK_VARIABLE_ADDRESS_ESCAPE (disabled by default), + STACK_VARIABLE_ADDRESS_ESCAPE (enabled by default), STARVATION (enabled by default), STATIC_INITIALIZATION_ORDER_FIASCO (enabled by default), STRICT_MODE_VIOLATION (enabled by default), diff --git a/infer/man/man1/infer-report.txt b/infer/man/man1/infer-report.txt index ece5c33fa..13350c923 100644 --- a/infer/man/man1/infer-report.txt +++ b/infer/man/man1/infer-report.txt @@ -84,6 +84,11 @@ OPTIONS Abduction_case_not_implemented (enabled by default), Array_of_pointsto (enabled by default), Assert_failure (enabled by default), + BIABD_CONDITION_ALWAYS_FALSE (disabled by default), + BIABD_CONDITION_ALWAYS_TRUE (disabled by default), + BIABD_REGISTERED_OBSERVER_BEING_DEALLOCATED (enabled by + default), + BIABD_STACK_VARIABLE_ADDRESS_ESCAPE (disabled by default), BIABD_USE_AFTER_FREE (enabled by default), BUFFER_OVERRUN_L1 (enabled by default), BUFFER_OVERRUN_L2 (enabled by default), @@ -181,6 +186,7 @@ OPTIONS IVAR_NOT_NULL_CHECKED (enabled by default), Internal_error (enabled by default), JAVASCRIPT_INJECTION (enabled by default), + LAB_RESOURCE_LEAK (enabled by default), LOCKLESS_VIOLATION (enabled by default), LOCK_CONSISTENCY_VIOLATION (enabled by default), LOGGING_PRIVATE_DATA (enabled by default), @@ -203,7 +209,6 @@ OPTIONS PULSE_MEMORY_LEAK (disabled by default), PURE_FUNCTION (enabled by default), QUANDARY_TAINT_ERROR (enabled by default), - REGISTERED_OBSERVER_BEING_DEALLOCATED (enabled by default), RESOURCE_LEAK (enabled by default), RETAIN_CYCLE (enabled by default), SHELL_INJECTION (enabled by default), @@ -212,7 +217,7 @@ OPTIONS SKIP_POINTER_DEREFERENCE (disabled by default), SQL_INJECTION (enabled by default), SQL_INJECTION_RISK (enabled by default), - STACK_VARIABLE_ADDRESS_ESCAPE (disabled by default), + STACK_VARIABLE_ADDRESS_ESCAPE (enabled by default), STARVATION (enabled by default), STATIC_INITIALIZATION_ORDER_FIASCO (enabled by default), STRICT_MODE_VIOLATION (enabled by default), diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index a369ffe2b..59a863c9d 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -358,6 +358,11 @@ OPTIONS Abduction_case_not_implemented (enabled by default), Array_of_pointsto (enabled by default), Assert_failure (enabled by default), + BIABD_CONDITION_ALWAYS_FALSE (disabled by default), + BIABD_CONDITION_ALWAYS_TRUE (disabled by default), + BIABD_REGISTERED_OBSERVER_BEING_DEALLOCATED (enabled by + default), + BIABD_STACK_VARIABLE_ADDRESS_ESCAPE (disabled by default), BIABD_USE_AFTER_FREE (enabled by default), BUFFER_OVERRUN_L1 (enabled by default), BUFFER_OVERRUN_L2 (enabled by default), @@ -455,6 +460,7 @@ OPTIONS IVAR_NOT_NULL_CHECKED (enabled by default), Internal_error (enabled by default), JAVASCRIPT_INJECTION (enabled by default), + LAB_RESOURCE_LEAK (enabled by default), LOCKLESS_VIOLATION (enabled by default), LOCK_CONSISTENCY_VIOLATION (enabled by default), LOGGING_PRIVATE_DATA (enabled by default), @@ -477,7 +483,6 @@ OPTIONS PULSE_MEMORY_LEAK (disabled by default), PURE_FUNCTION (enabled by default), QUANDARY_TAINT_ERROR (enabled by default), - REGISTERED_OBSERVER_BEING_DEALLOCATED (enabled by default), RESOURCE_LEAK (enabled by default), RETAIN_CYCLE (enabled by default), SHELL_INJECTION (enabled by default), @@ -486,7 +491,7 @@ OPTIONS SKIP_POINTER_DEREFERENCE (disabled by default), SQL_INJECTION (enabled by default), SQL_INJECTION_RISK (enabled by default), - STACK_VARIABLE_ADDRESS_ESCAPE (disabled by default), + STACK_VARIABLE_ADDRESS_ESCAPE (enabled by default), STARVATION (enabled by default), STATIC_INITIALIZATION_ORDER_FIASCO (enabled by default), STRICT_MODE_VIOLATION (enabled by default), diff --git a/infer/src/IR/Errlog.ml b/infer/src/IR/Errlog.ml index 7d532f10d..0fe8ff68e 100644 --- a/infer/src/IR/Errlog.ml +++ b/infer/src/IR/Errlog.ml @@ -204,11 +204,11 @@ let log_issue severity err_log ~loc ~node ~session ~ltr ~linters_def_file ~doc_u let error = Exceptions.recognize_exception exn in if not (IssueType.checker_can_report checker error.name) then L.die InternalError - "Issue type \"%s\" cannot be reported by the checker \"%s\". The only checkers that are \ - expected to produce this error type are [%a]. If this is incorrect please either update the \ + "Issue type \"%s\" cannot be reported by the checker \"%s\". The only checker that is \ + allowed to report this issue type is \"%s\". If this is incorrect please either update the \ issue in IssueType or create a new issue type for \"%s\"." - error.name.unique_id (Checker.get_name checker) (Pp.seq F.pp_print_string) - (List.map ~f:Checker.get_name error.name.checkers) + error.name.unique_id (Checker.get_name checker) + (Checker.get_name error.name.checker) (Checker.get_name checker) ; let severity = Option.value error.severity ~default:severity in let hide_java_loc_zero = diff --git a/infer/src/IR/Exceptions.ml b/infer/src/IR/Exceptions.ml index 78e9a7d51..38a28fbf3 100644 --- a/infer/src/IR/Exceptions.ml +++ b/infer/src/IR/Exceptions.ml @@ -205,7 +205,9 @@ let recognize_exception exn = ; severity= None ; category= Prover } | Condition_always_true_false (desc, b, ocaml_pos) -> - let name = if b then IssueType.condition_always_true else IssueType.condition_always_false in + let name = + if b then IssueType.biabd_condition_always_true else IssueType.biabd_condition_always_false + in { name ; description= desc ; ocaml_pos= Some ocaml_pos @@ -213,7 +215,7 @@ let recognize_exception exn = ; severity= None ; category= Nocat } | Custom_error (error_msg, desc) -> - { name= IssueType.register_from_string ~id:error_msg [Biabduction] + { name= IssueType.register_from_string ~id:error_msg Biabduction ; description= desc ; ocaml_pos= None ; visibility= Exn_user @@ -410,14 +412,14 @@ let recognize_exception exn = ; severity= None ; category= Prover } | Registered_observer_being_deallocated (desc, ocaml_pos) -> - { name= IssueType.registered_observer_being_deallocated + { name= IssueType.biabd_registered_observer_being_deallocated ; description= desc ; ocaml_pos= Some ocaml_pos ; visibility= Exn_user ; severity= Some Error ; category= Nocat } | Stack_variable_address_escape (desc, ocaml_pos) -> - { name= IssueType.stack_variable_address_escape + { name= IssueType.biabd_stack_variable_address_escape ; description= desc ; ocaml_pos= Some ocaml_pos ; visibility= Exn_user diff --git a/infer/src/al/ALIssues.ml b/infer/src/al/ALIssues.ml index d3787a2c1..b5fd3c934 100644 --- a/infer/src/al/ALIssues.ml +++ b/infer/src/al/ALIssues.ml @@ -263,7 +263,7 @@ let create_parsed_linters linters_def_file checkers : linter list = issue_desc.issue_type.doc_url in IssueType.register_from_string ~id:checker.id ?hum:issue_desc.issue_type.name ?doc_url - ~linters_def_file [Linters] + ~linters_def_file Linters in let issue_desc = {issue_desc with issue_type} in L.(debug Linters Medium) "@\nIssue_desc = %a@\n" CIssue.pp_issue issue_desc ; diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 29ce48283..6ad610d3e 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1184,7 +1184,7 @@ and () = let (_ : string list ref) = CLOpt.mk_string_list ?deprecated ~long ~f:(fun issue_id -> - let issue = IssueType.register_from_string ~id:issue_id [Linters] in + let issue = IssueType.register_from_string ~id:issue_id Linters in IssueType.set_enabled issue b ; issue_id ) ?default ~meta:"issue_type" diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index c10438d1e..51fa9b3f8 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -11,7 +11,7 @@ open! IStd module Unsafe : sig type t = private { unique_id: string - ; checkers: Checker.t list + ; checker: Checker.t ; mutable enabled: bool ; mutable hum: string ; mutable doc_url: string option @@ -26,7 +26,7 @@ module Unsafe : sig -> ?doc_url:string -> ?linters_def_file:string -> id:string - -> Checker.t list + -> Checker.t -> t val register_from_cost_string : @@ -43,7 +43,7 @@ end = struct module T = struct type t = { unique_id: string - ; checkers: Checker.t list + ; checker: Checker.t ; mutable enabled: bool ; mutable hum: string ; mutable doc_url: string option @@ -79,9 +79,9 @@ end = struct definitely. The [hum]an-readable description can be updated when we encounter the definition of the issue type, eg in AL. *) let register_from_string ?(enabled = true) ?hum:hum0 ?doc_url ?linters_def_file ~id:unique_id - checkers = + checker = let hum = match hum0 with Some str -> str | _ -> prettify unique_id in - let issue = {unique_id; checkers; enabled; hum; doc_url; linters_def_file} in + let issue = {unique_id; checker; enabled; hum; doc_url; linters_def_file} 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 @@ -100,7 +100,7 @@ end = struct = let issue_type_base = Format.asprintf s (CostKind.to_issue_string kind) in let issue_type = if is_on_ui_thread then issue_type_base ^ "_UI_THREAD" else issue_type_base in - register_from_string ~enabled ~id:issue_type [Cost] + register_from_string ~enabled ~id:issue_type Cost let all_issues () = IssueSet.elements !all_issues @@ -111,223 +111,240 @@ include Unsafe (** pretty print a localised string *) let pp fmt t = Format.pp_print_string fmt t.unique_id -let checker_can_report checker {checkers} = List.mem ~equal:Checker.equal checkers checker +let checker_can_report reporting_checker {checker= allowed_checker} = + Checker.equal reporting_checker allowed_checker + let abduction_case_not_implemented = - register_from_string ~id:"Abduction_case_not_implemented" [Biabduction] + register_from_string ~id:"Abduction_case_not_implemented" Biabduction -let analysis_stops = register_from_string ~enabled:false ~id:"ANALYSIS_STOPS" [Biabduction] +let analysis_stops = register_from_string ~enabled:false ~id:"ANALYSIS_STOPS" Biabduction -let array_of_pointsto = register_from_string ~id:"Array_of_pointsto" [Biabduction] +let array_of_pointsto = register_from_string ~id:"Array_of_pointsto" Biabduction let array_out_of_bounds_l1 = - register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L1" [Biabduction] + register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L1" Biabduction let array_out_of_bounds_l2 = - register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L2" [Biabduction] + register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L2" Biabduction let array_out_of_bounds_l3 = - register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L3" [Biabduction] + register_from_string ~enabled:false ~id:"ARRAY_OUT_OF_BOUNDS_L3" Biabduction + + +let assert_failure = register_from_string ~id:"Assert_failure" Biabduction + +let bad_footprint = register_from_string ~id:"Bad_footprint" Biabduction + +let biabd_condition_always_false = + register_from_string ~enabled:false ~id:"BIABD_CONDITION_ALWAYS_FALSE" Biabduction + + +let biabd_condition_always_true = + register_from_string ~enabled:false ~id:"BIABD_CONDITION_ALWAYS_TRUE" Biabduction -let assert_failure = register_from_string ~id:"Assert_failure" [Biabduction] +let biabd_registered_observer_being_deallocated = + register_from_string ~id:"BIABD_REGISTERED_OBSERVER_BEING_DEALLOCATED" Biabduction -let bad_footprint = register_from_string ~id:"Bad_footprint" [Biabduction] -let buffer_overrun_l1 = register_from_string ~id:"BUFFER_OVERRUN_L1" [BufferOverrunChecker] +let biabd_stack_variable_address_escape = + register_from_string ~enabled:false ~id:"BIABD_STACK_VARIABLE_ADDRESS_ESCAPE" Biabduction -let buffer_overrun_l2 = register_from_string ~id:"BUFFER_OVERRUN_L2" [BufferOverrunChecker] -let buffer_overrun_l3 = register_from_string ~id:"BUFFER_OVERRUN_L3" [BufferOverrunChecker] +let buffer_overrun_l1 = register_from_string ~id:"BUFFER_OVERRUN_L1" BufferOverrunChecker + +let buffer_overrun_l2 = register_from_string ~id:"BUFFER_OVERRUN_L2" BufferOverrunChecker + +let buffer_overrun_l3 = register_from_string ~id:"BUFFER_OVERRUN_L3" BufferOverrunChecker let buffer_overrun_l4 = - register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L4" [BufferOverrunChecker] + register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L4" BufferOverrunChecker let buffer_overrun_l5 = - register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L5" [BufferOverrunChecker] + register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_L5" BufferOverrunChecker -let buffer_overrun_r2 = register_from_string ~id:"BUFFER_OVERRUN_R2" [BufferOverrunChecker] +let buffer_overrun_r2 = register_from_string ~id:"BUFFER_OVERRUN_R2" BufferOverrunChecker -let buffer_overrun_s2 = register_from_string ~id:"BUFFER_OVERRUN_S2" [BufferOverrunChecker] +let buffer_overrun_s2 = register_from_string ~id:"BUFFER_OVERRUN_S2" BufferOverrunChecker -let buffer_overrun_t1 = register_from_string ~id:"BUFFER_OVERRUN_T1" [BufferOverrunChecker] +let buffer_overrun_t1 = register_from_string ~id:"BUFFER_OVERRUN_T1" BufferOverrunChecker let buffer_overrun_u5 = - register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_U5" [BufferOverrunChecker] + register_from_string ~enabled:false ~id:"BUFFER_OVERRUN_U5" BufferOverrunChecker -let cannot_star = register_from_string ~id:"Cannot_star" [Biabduction] +let cannot_star = register_from_string ~id:"Cannot_star" Biabduction let captured_strong_self = - register_from_string ~id:"CAPTURED_STRONG_SELF" ~hum:"Captured strongSelf" [SelfInBlock] + register_from_string ~id:"CAPTURED_STRONG_SELF" ~hum:"Captured strongSelf" SelfInBlock let checkers_allocates_memory = register_from_string ~id:"CHECKERS_ALLOCATES_MEMORY" ~hum:"Allocates Memory" - [AnnotationReachability] + AnnotationReachability let checkers_annotation_reachability_error = register_from_string ~id:"CHECKERS_ANNOTATION_REACHABILITY_ERROR" - ~hum:"Annotation Reachability Error" [AnnotationReachability] + ~hum:"Annotation Reachability Error" AnnotationReachability let checkers_calls_expensive_method = register_from_string ~id:"CHECKERS_CALLS_EXPENSIVE_METHOD" ~hum:"Expensive Method Called" - [AnnotationReachability] + AnnotationReachability let checkers_expensive_overrides_unexpensive = register_from_string ~id:"CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED" - ~hum:"Expensive Overrides Unannotated" [AnnotationReachability] + ~hum:"Expensive Overrides Unannotated" AnnotationReachability let checkers_fragment_retain_view = register_from_string ~id:"CHECKERS_FRAGMENT_RETAINS_VIEW" ~hum:"Fragment Retains View" - [FragmentRetainsView] + FragmentRetainsView -let checkers_immutable_cast = register_from_string ~id:"CHECKERS_IMMUTABLE_CAST" [ImmutableCast] +let checkers_immutable_cast = register_from_string ~id:"CHECKERS_IMMUTABLE_CAST" ImmutableCast -let checkers_printf_args = register_from_string ~id:"CHECKERS_PRINTF_ARGS" [PrintfArgs] +let checkers_printf_args = register_from_string ~id:"CHECKERS_PRINTF_ARGS" PrintfArgs let class_cast_exception = - register_from_string ~enabled:false ~id:"CLASS_CAST_EXCEPTION" [Biabduction] + register_from_string ~enabled:false ~id:"CLASS_CAST_EXCEPTION" Biabduction -let class_load = register_from_string ~id:"CLASS_LOAD" [ClassLoads] +let class_load = register_from_string ~id:"CLASS_LOAD" ClassLoads -let component_factory_function = register_from_string ~id:"COMPONENT_FACTORY_FUNCTION" [Linters] +let component_factory_function = register_from_string ~id:"COMPONENT_FACTORY_FUNCTION" Linters let component_file_cyclomatic_complexity = - register_from_string ~id:"COMPONENT_FILE_CYCLOMATIC_COMPLEXITY" [Linters] + register_from_string ~id:"COMPONENT_FILE_CYCLOMATIC_COMPLEXITY" Linters let component_file_line_count = - register_from_string ~enabled:false ~id:"COMPONENT_FILE_LINE_COUNT" [Linters] + register_from_string ~enabled:false ~id:"COMPONENT_FILE_LINE_COUNT" Linters let component_initializer_with_side_effects = - register_from_string ~id:"COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS" [Linters] + register_from_string ~id:"COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS" Linters let component_with_multiple_factory_methods = - register_from_string ~id:"COMPONENT_WITH_MULTIPLE_FACTORY_METHODS" [Linters] + register_from_string ~id:"COMPONENT_WITH_MULTIPLE_FACTORY_METHODS" Linters let component_with_unconventional_superclass = - register_from_string ~id:"COMPONENT_WITH_UNCONVENTIONAL_SUPERCLASS" [Linters] + register_from_string ~id:"COMPONENT_WITH_UNCONVENTIONAL_SUPERCLASS" Linters let condition_always_false = - register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_FALSE" - [Biabduction; BufferOverrunChecker] + register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_FALSE" BufferOverrunChecker let condition_always_true = - register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_TRUE" [Biabduction; BufferOverrunChecker] + register_from_string ~enabled:false ~id:"CONDITION_ALWAYS_TRUE" BufferOverrunChecker let constant_address_dereference = - register_from_string ~enabled:false ~id:"CONSTANT_ADDRESS_DEREFERENCE" [Pulse] + register_from_string ~enabled:false ~id:"CONSTANT_ADDRESS_DEREFERENCE" Pulse -let create_intent_from_uri = register_from_string ~id:"CREATE_INTENT_FROM_URI" [Quandary] +let create_intent_from_uri = register_from_string ~id:"CREATE_INTENT_FROM_URI" Quandary -let cross_site_scripting = register_from_string ~id:"CROSS_SITE_SCRIPTING" [Quandary] +let cross_site_scripting = register_from_string ~id:"CROSS_SITE_SCRIPTING" Quandary let dangling_pointer_dereference = - register_from_string ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE" [Biabduction] + register_from_string ~enabled:false ~id:"DANGLING_POINTER_DEREFERENCE" Biabduction -let dead_store = register_from_string ~id:"DEAD_STORE" [Liveness] +let dead_store = register_from_string ~id:"DEAD_STORE" Liveness -let deadlock = register_from_string ~id:"DEADLOCK" [Starvation] +let deadlock = register_from_string ~id:"DEADLOCK" Starvation -let deallocate_stack_variable = register_from_string ~id:"DEALLOCATE_STACK_VARIABLE" [Biabduction] +let deallocate_stack_variable = register_from_string ~id:"DEALLOCATE_STACK_VARIABLE" Biabduction -let deallocate_static_memory = register_from_string ~id:"DEALLOCATE_STATIC_MEMORY" [Biabduction] +let deallocate_static_memory = register_from_string ~id:"DEALLOCATE_STATIC_MEMORY" Biabduction -let deallocation_mismatch = register_from_string ~id:"DEALLOCATION_MISMATCH" [Biabduction] +let deallocation_mismatch = register_from_string ~id:"DEALLOCATION_MISMATCH" Biabduction -let divide_by_zero = register_from_string ~enabled:false ~id:"DIVIDE_BY_ZERO" [Biabduction] +let divide_by_zero = register_from_string ~enabled:false ~id:"DIVIDE_BY_ZERO" Biabduction -let do_not_report = register_from_string ~id:"DO_NOT_REPORT" [Quandary] +let do_not_report = register_from_string ~id:"DO_NOT_REPORT" Quandary -let empty_vector_access = register_from_string ~id:"EMPTY_VECTOR_ACCESS" [Biabduction] +let empty_vector_access = register_from_string ~id:"EMPTY_VECTOR_ACCESS" Biabduction let eradicate_condition_redundant = - register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT" ~hum:"Condition Redundant" [Eradicate] + register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT" ~hum:"Condition Redundant" Eradicate (* TODO(T54070503) remove condition redundant nonnull *) let _ = register_from_string ~id:"ERADICATE_CONDITION_REDUNDANT_NONNULL" - ~hum:"Condition Redundant Non-Null" [Eradicate] + ~hum:"Condition Redundant Non-Null" Eradicate let eradicate_field_not_initialized = - register_from_string ~id:"ERADICATE_FIELD_NOT_INITIALIZED" ~hum:"Field Not Initialized" [Eradicate] + register_from_string ~id:"ERADICATE_FIELD_NOT_INITIALIZED" ~hum:"Field Not Initialized" Eradicate let eradicate_field_not_nullable = - register_from_string ~id:"ERADICATE_FIELD_NOT_NULLABLE" ~hum:"Field Not Nullable" [Eradicate] + register_from_string ~id:"ERADICATE_FIELD_NOT_NULLABLE" ~hum:"Field Not Nullable" Eradicate let eradicate_field_over_annotated = - register_from_string ~id:"ERADICATE_FIELD_OVER_ANNOTATED" ~hum:"Field Over Annotated" [Eradicate] + register_from_string ~id:"ERADICATE_FIELD_OVER_ANNOTATED" ~hum:"Field Over Annotated" Eradicate let eradicate_inconsistent_subclass_parameter_annotation = register_from_string ~id:"ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION" - ~hum:"Inconsistent Subclass Parameter Annotation" [Eradicate] + ~hum:"Inconsistent Subclass Parameter Annotation" Eradicate let eradicate_inconsistent_subclass_return_annotation = register_from_string ~id:"ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION" - ~hum:"Inconsistent Subclass Return Annotation" [Eradicate] + ~hum:"Inconsistent Subclass Return Annotation" Eradicate let eradicate_redundant_nested_class_annotation = register_from_string ~id:"ERADICATE_REDUNDANT_NESTED_CLASS_ANNOTATION" - ~hum:"@Nullsafe annotation is redundant" [Eradicate] + ~hum:"@Nullsafe annotation is redundant" Eradicate let eradicate_bad_nested_class_annotation = register_from_string ~id:"ERADICATE_BAD_NESTED_CLASS_ANNOTATION" - ~hum:"@Nullsafe annotation is inconsistent with outer class" [Eradicate] + ~hum:"@Nullsafe annotation is inconsistent with outer class" Eradicate let eradicate_nullable_dereference = - register_from_string ~id:"ERADICATE_NULLABLE_DEREFERENCE" ~hum:"Nullable Dereference" [Eradicate] + register_from_string ~id:"ERADICATE_NULLABLE_DEREFERENCE" ~hum:"Nullable Dereference" Eradicate let eradicate_parameter_not_nullable = register_from_string ~id:"ERADICATE_PARAMETER_NOT_NULLABLE" ~hum:"Parameter Not Nullable" - [Eradicate] + Eradicate let eradicate_return_not_nullable = - register_from_string ~id:"ERADICATE_RETURN_NOT_NULLABLE" ~hum:"Return Not Nullable" [Eradicate] + register_from_string ~id:"ERADICATE_RETURN_NOT_NULLABLE" ~hum:"Return Not Nullable" Eradicate let eradicate_return_over_annotated = - register_from_string ~id:"ERADICATE_RETURN_OVER_ANNOTATED" ~hum:"Return Over Annotated" [Eradicate] + register_from_string ~id:"ERADICATE_RETURN_OVER_ANNOTATED" ~hum:"Return Over Annotated" Eradicate let eradicate_unchecked_usage_in_nullsafe = register_from_string ~id:"ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE" - ~hum:"Nullsafe mode: unchecked usage of a value" [Eradicate] + ~hum:"Nullsafe mode: unchecked usage of a value" Eradicate let eradicate_unvetted_third_party_in_nullsafe = register_from_string ~id:"ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE" - ~hum:"Nullsafe mode: unchecked usage of unvetted third-party" [Eradicate] + ~hum:"Nullsafe mode: unchecked usage of unvetted third-party" Eradicate (* Meta issues in eradicate are technical issues reflecting null-safety state of classes in general, @@ -337,7 +354,7 @@ let eradicate_meta_class_is_nullsafe = register_from_string ~id:"ERADICATE_META_CLASS_IS_NULLSAFE" ~hum: "Class is marked @Nullsafe and has 0 issues" (* Should be enabled for special integrations *) - ~enabled:false [Eradicate] + ~enabled:false Eradicate (* Class is either: @@ -348,14 +365,14 @@ let eradicate_meta_class_needs_improvement = register_from_string ~id:"ERADICATE_META_CLASS_NEEDS_IMPROVEMENT" ~hum: "Class needs improvement to become @Nullsafe" (* Should be enabled for special integrations *) - ~enabled:false [Eradicate] + ~enabled:false Eradicate let eradicate_meta_class_can_be_nullsafe = register_from_string ~id:"ERADICATE_META_CLASS_CAN_BE_NULLSAFE" ~hum: "Class has 0 issues and can be marked @Nullsafe" - (* Should be enabled for special integrations *) ~enabled:false [Eradicate] + (* Should be enabled for special integrations *) ~enabled:false Eradicate let expensive_cost_call ~kind ~is_on_ui_thread = @@ -363,248 +380,243 @@ let expensive_cost_call ~kind ~is_on_ui_thread = let exposed_insecure_intent_handling = - register_from_string ~id:"EXPOSED_INSECURE_INTENT_HANDLING" [Quandary] + register_from_string ~id:"EXPOSED_INSECURE_INTENT_HANDLING" Quandary -let failure_exe = register_from_string ~id:"Failure_exe" [Biabduction] +let failure_exe = register_from_string ~id:"Failure_exe" Biabduction -let field_not_null_checked = register_from_string ~id:"IVAR_NOT_NULL_CHECKED" [Biabduction] +let field_not_null_checked = register_from_string ~id:"IVAR_NOT_NULL_CHECKED" Biabduction (* from AL default linters *) let _global_variable_initialized_with_function_or_method_call = register_from_string ~enabled:false ~id:"GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL" - [Linters] + Linters let guardedby_violation_racerd = - register_from_string ~id:"GUARDEDBY_VIOLATION" ~hum:"GuardedBy Violation" [RacerD] + register_from_string ~id:"GUARDEDBY_VIOLATION" ~hum:"GuardedBy Violation" RacerD -let impure_function = register_from_string ~id:"IMPURE_FUNCTION" [Impurity] +let impure_function = register_from_string ~id:"IMPURE_FUNCTION" Impurity let inefficient_keyset_iterator = - register_from_string ~id:"INEFFICIENT_KEYSET_ITERATOR" [InefficientKeysetIterator] + register_from_string ~id:"INEFFICIENT_KEYSET_ITERATOR" InefficientKeysetIterator -let inferbo_alloc_is_big = register_from_string ~id:"INFERBO_ALLOC_IS_BIG" [BufferOverrunChecker] +let inferbo_alloc_is_big = register_from_string ~id:"INFERBO_ALLOC_IS_BIG" BufferOverrunChecker let inferbo_alloc_is_negative = - register_from_string ~id:"INFERBO_ALLOC_IS_NEGATIVE" [BufferOverrunChecker] + register_from_string ~id:"INFERBO_ALLOC_IS_NEGATIVE" BufferOverrunChecker -let inferbo_alloc_is_zero = register_from_string ~id:"INFERBO_ALLOC_IS_ZERO" [BufferOverrunChecker] +let inferbo_alloc_is_zero = register_from_string ~id:"INFERBO_ALLOC_IS_ZERO" BufferOverrunChecker let inferbo_alloc_may_be_big = - register_from_string ~id:"INFERBO_ALLOC_MAY_BE_BIG" [BufferOverrunChecker] + register_from_string ~id:"INFERBO_ALLOC_MAY_BE_BIG" BufferOverrunChecker let inferbo_alloc_may_be_negative = - register_from_string ~id:"INFERBO_ALLOC_MAY_BE_NEGATIVE" [BufferOverrunChecker] + register_from_string ~id:"INFERBO_ALLOC_MAY_BE_NEGATIVE" BufferOverrunChecker let inferbo_alloc_may_be_tainted = - register_from_string ~id:"INFERBO_ALLOC_MAY_BE_TAINTED" [BufferOverrunChecker] + register_from_string ~id:"INFERBO_ALLOC_MAY_BE_TAINTED" BufferOverrunChecker let infinite_cost_call ~kind = register_from_cost_string ~enabled:false "INFINITE_%s" ~kind let inherently_dangerous_function = - register_from_string ~id:"INHERENTLY_DANGEROUS_FUNCTION" [Biabduction] + register_from_string ~id:"INHERENTLY_DANGEROUS_FUNCTION" Biabduction -let insecure_intent_handling = register_from_string ~id:"INSECURE_INTENT_HANDLING" [Quandary] +let insecure_intent_handling = register_from_string ~id:"INSECURE_INTENT_HANDLING" Quandary -let integer_overflow_l1 = register_from_string ~id:"INTEGER_OVERFLOW_L1" [BufferOverrunChecker] +let integer_overflow_l1 = register_from_string ~id:"INTEGER_OVERFLOW_L1" BufferOverrunChecker -let integer_overflow_l2 = register_from_string ~id:"INTEGER_OVERFLOW_L2" [BufferOverrunChecker] +let integer_overflow_l2 = register_from_string ~id:"INTEGER_OVERFLOW_L2" BufferOverrunChecker let integer_overflow_l5 = - register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_L5" [BufferOverrunChecker] + register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_L5" BufferOverrunChecker -let integer_overflow_r2 = register_from_string ~id:"INTEGER_OVERFLOW_R2" [BufferOverrunChecker] +let integer_overflow_r2 = register_from_string ~id:"INTEGER_OVERFLOW_R2" BufferOverrunChecker let integer_overflow_u5 = - register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_U5" [BufferOverrunChecker] + register_from_string ~enabled:false ~id:"INTEGER_OVERFLOW_U5" BufferOverrunChecker + +let interface_not_thread_safe = register_from_string ~id:"INTERFACE_NOT_THREAD_SAFE" RacerD -let interface_not_thread_safe = register_from_string ~id:"INTERFACE_NOT_THREAD_SAFE" [RacerD] +let internal_error = register_from_string ~id:"Internal_error" Biabduction -let internal_error = register_from_string ~id:"Internal_error" [Biabduction] +let invariant_call = register_from_string ~enabled:false ~id:"INVARIANT_CALL" LoopHoisting -let invariant_call = register_from_string ~enabled:false ~id:"INVARIANT_CALL" [LoopHoisting] +let javascript_injection = register_from_string ~id:"JAVASCRIPT_INJECTION" Quandary -let javascript_injection = register_from_string ~id:"JAVASCRIPT_INJECTION" [Quandary] +let lab_resource_leak = register_from_string ~id:"LAB_RESOURCE_LEAK" ResourceLeakLabExercise let leak_after_array_abstraction = - register_from_string ~id:"Leak_after_array_abstraction" [Biabduction] + register_from_string ~id:"Leak_after_array_abstraction" Biabduction -let leak_in_footprint = register_from_string ~id:"Leak_in_footprint" [Biabduction] +let leak_in_footprint = register_from_string ~id:"Leak_in_footprint" Biabduction -let lock_consistency_violation = register_from_string ~id:"LOCK_CONSISTENCY_VIOLATION" [RacerD] +let lock_consistency_violation = register_from_string ~id:"LOCK_CONSISTENCY_VIOLATION" RacerD -let lockless_violation = register_from_string ~id:"LOCKLESS_VIOLATION" [Starvation] +let lockless_violation = register_from_string ~id:"LOCKLESS_VIOLATION" Starvation -let logging_private_data = register_from_string ~id:"LOGGING_PRIVATE_DATA" [Quandary] +let logging_private_data = register_from_string ~id:"LOGGING_PRIVATE_DATA" Quandary let expensive_loop_invariant_call = - register_from_string ~id:"EXPENSIVE_LOOP_INVARIANT_CALL" [LoopHoisting] + register_from_string ~id:"EXPENSIVE_LOOP_INVARIANT_CALL" LoopHoisting -let memory_leak = register_from_string ~id:"MEMORY_LEAK" [Biabduction] +let memory_leak = register_from_string ~id:"MEMORY_LEAK" Biabduction -let missing_fld = register_from_string ~id:"Missing_fld" ~hum:"Missing Field" [Biabduction] +let missing_fld = register_from_string ~id:"Missing_fld" ~hum:"Missing Field" Biabduction -let missing_required_prop = register_from_string ~id:"MISSING_REQUIRED_PROP" [LithoRequiredProps] +let missing_required_prop = register_from_string ~id:"MISSING_REQUIRED_PROP" LithoRequiredProps let mixed_self_weakself = - register_from_string ~id:"MIXED_SELF_WEAKSELF" ~hum:"Mixed Self WeakSelf" [SelfInBlock] + register_from_string ~id:"MIXED_SELF_WEAKSELF" ~hum:"Mixed Self WeakSelf" SelfInBlock let multiple_weakself = - register_from_string ~id:"MULTIPLE_WEAKSELF" ~hum:"Multiple WeakSelf Use" [SelfInBlock] + register_from_string ~id:"MULTIPLE_WEAKSELF" ~hum:"Multiple WeakSelf Use" SelfInBlock let mutable_local_variable_in_component_file = - register_from_string ~id:"MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE" [Linters] + register_from_string ~id:"MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE" Linters -let null_dereference = register_from_string ~id:"NULL_DEREFERENCE" [Biabduction] +let null_dereference = register_from_string ~id:"NULL_DEREFERENCE" Biabduction let null_test_after_dereference = - register_from_string ~enabled:false ~id:"NULL_TEST_AFTER_DEREFERENCE" [Biabduction] + register_from_string ~enabled:false ~id:"NULL_TEST_AFTER_DEREFERENCE" Biabduction -let nullptr_dereference = register_from_string ~enabled:false ~id:"NULLPTR_DEREFERENCE" [Pulse] +let nullptr_dereference = register_from_string ~enabled:false ~id:"NULLPTR_DEREFERENCE" Pulse -let parameter_not_null_checked = register_from_string ~id:"PARAMETER_NOT_NULL_CHECKED" [Biabduction] +let parameter_not_null_checked = register_from_string ~id:"PARAMETER_NOT_NULL_CHECKED" Biabduction -let pointer_size_mismatch = register_from_string ~id:"POINTER_SIZE_MISMATCH" [Biabduction] +let pointer_size_mismatch = register_from_string ~id:"POINTER_SIZE_MISMATCH" Biabduction -let precondition_not_found = register_from_string ~id:"PRECONDITION_NOT_FOUND" [Biabduction] +let precondition_not_found = register_from_string ~id:"PRECONDITION_NOT_FOUND" Biabduction -let precondition_not_met = register_from_string ~id:"PRECONDITION_NOT_MET" [Biabduction] +let precondition_not_met = register_from_string ~id:"PRECONDITION_NOT_MET" Biabduction let premature_nil_termination = - register_from_string ~id:"PREMATURE_NIL_TERMINATION_ARGUMENT" [Biabduction] + register_from_string ~id:"PREMATURE_NIL_TERMINATION_ARGUMENT" Biabduction -let pulse_memory_leak = register_from_string ~enabled:false ~id:"PULSE_MEMORY_LEAK" [Pulse] +let pulse_memory_leak = register_from_string ~enabled:false ~id:"PULSE_MEMORY_LEAK" Pulse -let pure_function = register_from_string ~id:"PURE_FUNCTION" [Purity] +let pure_function = register_from_string ~id:"PURE_FUNCTION" Purity -let quandary_taint_error = register_from_string ~id:"QUANDARY_TAINT_ERROR" [Quandary] +let quandary_taint_error = register_from_string ~id:"QUANDARY_TAINT_ERROR" Quandary -let registered_observer_being_deallocated = - register_from_string ~id:"REGISTERED_OBSERVER_BEING_DEALLOCATED" [Biabduction; Linters] +let resource_leak = register_from_string ~id:"RESOURCE_LEAK" Biabduction +let retain_cycle = register_from_string ~enabled:true ~id:"RETAIN_CYCLE" Biabduction -let resource_leak = register_from_string ~id:"RESOURCE_LEAK" [Biabduction; ResourceLeakLabExercise] - -let retain_cycle = register_from_string ~enabled:true ~id:"RETAIN_CYCLE" [Biabduction] - -let skip_function = register_from_string ~enabled:false ~id:"SKIP_FUNCTION" [Biabduction] +let skip_function = register_from_string ~enabled:false ~id:"SKIP_FUNCTION" Biabduction let skip_pointer_dereference = - register_from_string ~enabled:false ~id:"SKIP_POINTER_DEREFERENCE" [Biabduction] - + register_from_string ~enabled:false ~id:"SKIP_POINTER_DEREFERENCE" Biabduction -let shell_injection = register_from_string ~id:"SHELL_INJECTION" [Quandary] -let shell_injection_risk = register_from_string ~id:"SHELL_INJECTION_RISK" [Quandary] +let shell_injection = register_from_string ~id:"SHELL_INJECTION" Quandary -let sql_injection = register_from_string ~id:"SQL_INJECTION" [Quandary] +let shell_injection_risk = register_from_string ~id:"SHELL_INJECTION_RISK" Quandary -let sql_injection_risk = register_from_string ~id:"SQL_INJECTION_RISK" [Quandary] +let sql_injection = register_from_string ~id:"SQL_INJECTION" Quandary -let stack_variable_address_escape = - register_from_string ~enabled:false ~id:"STACK_VARIABLE_ADDRESS_ESCAPE" [Biabduction; Pulse] +let sql_injection_risk = register_from_string ~id:"SQL_INJECTION_RISK" Quandary +let stack_variable_address_escape = register_from_string ~id:"STACK_VARIABLE_ADDRESS_ESCAPE" Pulse -let starvation = register_from_string ~id:"STARVATION" ~hum:"UI Thread Starvation" [Starvation] +let starvation = register_from_string ~id:"STARVATION" ~hum:"UI Thread Starvation" Starvation let static_initialization_order_fiasco = - register_from_string ~id:"STATIC_INITIALIZATION_ORDER_FIASCO" [SIOF] + register_from_string ~id:"STATIC_INITIALIZATION_ORDER_FIASCO" SIOF let strict_mode_violation = - register_from_string ~id:"STRICT_MODE_VIOLATION" ~hum:"Strict Mode Violation" [Starvation] + register_from_string ~id:"STRICT_MODE_VIOLATION" ~hum:"Strict Mode Violation" Starvation let strong_self_not_checked = - register_from_string ~id:"STRONG_SELF_NOT_CHECKED" ~hum:"StrongSelf Not Checked" [SelfInBlock] + register_from_string ~id:"STRONG_SELF_NOT_CHECKED" ~hum:"StrongSelf Not Checked" SelfInBlock let symexec_memory_error = - register_from_string ~id:"Symexec_memory_error" ~hum:"Symbolic Execution Memory Error" - [Biabduction] + register_from_string ~id:"Symexec_memory_error" ~hum:"Symbolic Execution Memory Error" Biabduction -let thread_safety_violation = register_from_string ~id:"THREAD_SAFETY_VIOLATION" [RacerD] +let thread_safety_violation = register_from_string ~id:"THREAD_SAFETY_VIOLATION" RacerD let complexity_increase ~kind ~is_on_ui_thread = register_from_cost_string ~kind ~is_on_ui_thread "%s_COMPLEXITY_INCREASE" -let topl_error = register_from_string ~id:"TOPL_ERROR" [TOPL] +let topl_error = register_from_string ~id:"TOPL_ERROR" TOPL let unary_minus_applied_to_unsigned_expression = - register_from_string ~enabled:false ~id:"UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" [Biabduction] + register_from_string ~enabled:false ~id:"UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION" Biabduction -let uninitialized_value = register_from_string ~id:"UNINITIALIZED_VALUE" [Uninit] +let uninitialized_value = register_from_string ~id:"UNINITIALIZED_VALUE" Uninit -let unreachable_code_after = register_from_string ~id:"UNREACHABLE_CODE" [BufferOverrunChecker] +let unreachable_code_after = register_from_string ~id:"UNREACHABLE_CODE" BufferOverrunChecker -let use_after_delete = register_from_string ~id:"USE_AFTER_DELETE" [Pulse] +let use_after_delete = register_from_string ~id:"USE_AFTER_DELETE" Pulse -let use_after_free = register_from_string ~id:"USE_AFTER_FREE" [Pulse] +let use_after_free = register_from_string ~id:"USE_AFTER_FREE" Pulse -let biabd_use_after_free = register_from_string ~id:"BIABD_USE_AFTER_FREE" [Biabduction] +let biabd_use_after_free = register_from_string ~id:"BIABD_USE_AFTER_FREE" Biabduction -let use_after_lifetime = register_from_string ~id:"USE_AFTER_LIFETIME" [Pulse] +let use_after_lifetime = register_from_string ~id:"USE_AFTER_LIFETIME" Pulse -let user_controlled_sql_risk = register_from_string ~id:"USER_CONTROLLED_SQL_RISK" [Quandary] +let user_controlled_sql_risk = register_from_string ~id:"USER_CONTROLLED_SQL_RISK" Quandary let untrusted_buffer_access = - register_from_string ~enabled:false ~id:"UNTRUSTED_BUFFER_ACCESS" [Quandary] + register_from_string ~enabled:false ~id:"UNTRUSTED_BUFFER_ACCESS" Quandary -let untrusted_deserialization = register_from_string ~id:"UNTRUSTED_DESERIALIZATION" [Quandary] +let untrusted_deserialization = register_from_string ~id:"UNTRUSTED_DESERIALIZATION" Quandary let untrusted_deserialization_risk = - register_from_string ~id:"UNTRUSTED_DESERIALIZATION_RISK" [Quandary] + register_from_string ~id:"UNTRUSTED_DESERIALIZATION_RISK" Quandary let untrusted_environment_change_risk = - register_from_string ~id:"UNTRUSTED_ENVIRONMENT_CHANGE_RISK" [Quandary] + register_from_string ~id:"UNTRUSTED_ENVIRONMENT_CHANGE_RISK" Quandary -let untrusted_file = register_from_string ~id:"UNTRUSTED_FILE" [Quandary] +let untrusted_file = register_from_string ~id:"UNTRUSTED_FILE" Quandary -let untrusted_file_risk = register_from_string ~id:"UNTRUSTED_FILE_RISK" [Quandary] +let untrusted_file_risk = register_from_string ~id:"UNTRUSTED_FILE_RISK" Quandary let untrusted_heap_allocation = - register_from_string ~enabled:false ~id:"UNTRUSTED_HEAP_ALLOCATION" [Quandary] + register_from_string ~enabled:false ~id:"UNTRUSTED_HEAP_ALLOCATION" Quandary -let untrusted_intent_creation = register_from_string ~id:"UNTRUSTED_INTENT_CREATION" [Quandary] +let untrusted_intent_creation = register_from_string ~id:"UNTRUSTED_INTENT_CREATION" Quandary -let untrusted_url_risk = register_from_string ~id:"UNTRUSTED_URL_RISK" [Quandary] +let untrusted_url_risk = register_from_string ~id:"UNTRUSTED_URL_RISK" Quandary let untrusted_variable_length_array = - register_from_string ~id:"UNTRUSTED_VARIABLE_LENGTH_ARRAY" [Quandary] + register_from_string ~id:"UNTRUSTED_VARIABLE_LENGTH_ARRAY" Quandary -let vector_invalidation = register_from_string ~id:"VECTOR_INVALIDATION" [Pulse] +let vector_invalidation = register_from_string ~id:"VECTOR_INVALIDATION" Pulse let weak_self_in_noescape_block = - register_from_string ~id:"WEAK_SELF_IN_NO_ESCAPE_BLOCK" [SelfInBlock] + register_from_string ~id:"WEAK_SELF_IN_NO_ESCAPE_BLOCK" SelfInBlock let wrong_argument_number = - register_from_string ~id:"Wrong_argument_number" ~hum:"Wrong Argument Number" [Biabduction] + register_from_string ~id:"Wrong_argument_number" ~hum:"Wrong Argument Number" Biabduction let unreachable_cost_call ~kind = diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli index ae09e36da..f2445dfc3 100644 --- a/infer/src/base/IssueType.mli +++ b/infer/src/base/IssueType.mli @@ -7,10 +7,9 @@ open! IStd -(** type of string used for localisation *) type t = private { unique_id: string - ; checkers: Checker.t list + ; checker: Checker.t ; mutable enabled: bool ; mutable hum: string ; mutable doc_url: string option @@ -31,7 +30,7 @@ val register_from_string : -> ?doc_url:string -> ?linters_def_file:string -> id:string - -> Checker.t list + -> Checker.t -> t (** Create a new issue and register it in the list of all issues. NOTE: if the issue with the same string id is already registered, overrides `hum`, `doc_url`, and `linters_def_file`, but DOES @@ -62,6 +61,14 @@ val assert_failure : t val bad_footprint : t +val biabd_condition_always_false : t + +val biabd_condition_always_true : t + +val biabd_registered_observer_being_deallocated : t + +val biabd_stack_variable_address_escape : t + val biabd_use_after_free : t val buffer_overrun_l1 : t @@ -238,6 +245,8 @@ val invariant_call : t val javascript_injection : t +val lab_resource_leak : t + val leak_after_array_abstraction : t val leak_in_footprint : t @@ -284,8 +293,6 @@ val pure_function : t val quandary_taint_error : t -val registered_observer_being_deallocated : t - val resource_leak : t val retain_cycle : t diff --git a/infer/src/checkers/annotationReachability.ml b/infer/src/checkers/annotationReachability.ml index 98987435e..4aa0e892c 100644 --- a/infer/src/checkers/annotationReachability.ml +++ b/infer/src/checkers/annotationReachability.ml @@ -332,7 +332,7 @@ module CxxAnnotationSpecs = struct in let linters_def_file = Option.value_map ~default:"" ~f:Fn.id Config.inferconfig_file in IssueType.register_from_string ~id:spec_name ~doc_url ~linters_def_file - [AnnotationReachability] + AnnotationReachability in Reporting.log_error proc_desc err_log ~loc ~ltr:final_trace AnnotationReachability issue_type description diff --git a/infer/src/labs/01_integer_domain/ResourceLeaks.ml b/infer/src/labs/01_integer_domain/ResourceLeaks.ml index 7e71fe960..1ebcdafd6 100644 --- a/infer/src/labs/01_integer_domain/ResourceLeaks.ml +++ b/infer/src/labs/01_integer_domain/ResourceLeaks.ml @@ -88,7 +88,7 @@ let report_if_leak post summary (proc_data : unit ProcData.t) = if ResourceLeakDomain.has_leak post then let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in - Reporting.log_error summary ~loc:last_loc IssueType.resource_leak message + Reporting.log_error summary ~loc:last_loc IssueType.lab_resource_leak message (* Callback for invoking the checker from the outside--registered in RegisterCheckers *) diff --git a/infer/src/labs/02_domain_join/ResourceLeaks.ml b/infer/src/labs/02_domain_join/ResourceLeaks.ml index 7e71fe960..1ebcdafd6 100644 --- a/infer/src/labs/02_domain_join/ResourceLeaks.ml +++ b/infer/src/labs/02_domain_join/ResourceLeaks.ml @@ -88,7 +88,7 @@ let report_if_leak post summary (proc_data : unit ProcData.t) = if ResourceLeakDomain.has_leak post then let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in - Reporting.log_error summary ~loc:last_loc IssueType.resource_leak message + Reporting.log_error summary ~loc:last_loc IssueType.lab_resource_leak message (* Callback for invoking the checker from the outside--registered in RegisterCheckers *) diff --git a/infer/src/labs/03_domain_top/ResourceLeaks.ml b/infer/src/labs/03_domain_top/ResourceLeaks.ml index 7e71fe960..1ebcdafd6 100644 --- a/infer/src/labs/03_domain_top/ResourceLeaks.ml +++ b/infer/src/labs/03_domain_top/ResourceLeaks.ml @@ -88,7 +88,7 @@ let report_if_leak post summary (proc_data : unit ProcData.t) = if ResourceLeakDomain.has_leak post then let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in - Reporting.log_error summary ~loc:last_loc IssueType.resource_leak message + Reporting.log_error summary ~loc:last_loc IssueType.lab_resource_leak message (* Callback for invoking the checker from the outside--registered in RegisterCheckers *) diff --git a/infer/src/labs/04_interprocedural/ResourceLeaks.ml b/infer/src/labs/04_interprocedural/ResourceLeaks.ml index 6e77dcbd6..c1a741769 100644 --- a/infer/src/labs/04_interprocedural/ResourceLeaks.ml +++ b/infer/src/labs/04_interprocedural/ResourceLeaks.ml @@ -102,7 +102,7 @@ let report_if_leak post summary (proc_data : unit ProcData.t) = if ResourceLeakDomain.has_leak post then let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in - Reporting.log_error summary ~loc:last_loc IssueType.resource_leak message + Reporting.log_error summary ~loc:last_loc IssueType.lab_resource_leak message (* Callback for invoking the checker from the outside--registered in RegisterCheckers *) diff --git a/infer/src/labs/05_access_paths_interprocedural/ResourceLeaks.ml b/infer/src/labs/05_access_paths_interprocedural/ResourceLeaks.ml index 89785ea55..d2750f9e0 100644 --- a/infer/src/labs/05_access_paths_interprocedural/ResourceLeaks.ml +++ b/infer/src/labs/05_access_paths_interprocedural/ResourceLeaks.ml @@ -109,7 +109,7 @@ let report_if_leak post summary formal_map (proc_data : unit ProcData.t) = if ResourceLeakDomain.has_leak formal_map post then let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in - Reporting.log_error summary ~loc:last_loc IssueType.resource_leak message + Reporting.log_error summary ~loc:last_loc IssueType.lab_resource_leak message (* Callback for invoking the checker from the outside--registered in RegisterCheckers *) diff --git a/infer/src/labs/README.md b/infer/src/labs/README.md index aa5cda471..59a5d0c50 100644 --- a/infer/src/labs/README.md +++ b/infer/src/labs/README.md @@ -85,13 +85,7 @@ You don't need to change `join` or `widen` yet, this will be done later. You als Finally, look again at the HTML debug output of infer on [Leaks.java](https://github.com/facebook/infer/blob/master/infer/tests/codetoanalyze/java/lab/Leaks.java). You should see the resource count be incremented and decremented appropriately. -(c) Now let's report leaks! Write and expose a function `ResourceLeakDomain.has_leak`, true when an abstract state shows a leak. Then change `ResourceLeaks.report_if_leak` to report when `ResourceLeakDomain.has_leak post` is true. You can use this code to report: - -```OCaml - let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_data.pdesc) in - let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in - Reporting.log_error proc_desc err_log ~loc:last_loc IssueType.resource_leak message -``` +(c) Now let's report leaks! Write and expose a function `ResourceLeakDomain.has_leak`, true when an abstract state shows a leak. Then change `ResourceLeaks.report_if_leak` to report when `ResourceLeakDomain.has_leak post` is true. (d) Think about the concretization of the resource count. What does a resource count of zero mean? Is there a concrete state in the concretization of "Resource count zero" that leaks a resource? Write a simple test method `FN_leakBad` in [Leaks.java](https://github.com/facebook/infer/blob/master/infer/tests/codetoanalyze/java/lab/Leaks.java) that will produce this concrete state (that is, a false negative test where the program leaks a resource, but the analyzer doesn't catch it). diff --git a/infer/src/labs/ResourceLeaks.ml b/infer/src/labs/ResourceLeaks.ml index 989876ce9..4494bc443 100644 --- a/infer/src/labs/ResourceLeaks.ml +++ b/infer/src/labs/ResourceLeaks.ml @@ -76,7 +76,14 @@ module CFG = ProcCfg.Normal module Analyzer = LowerHil.MakeAbstractInterpreter (TransferFunctions (CFG)) (** Report an error when we have acquired more resources than we have released *) -let report_if_leak {InterproceduralAnalysis.proc_desc= _; err_log= _; _} _post = () +let report_if_leak {InterproceduralAnalysis.proc_desc; err_log; _} post = + let change_me = false in + if change_me then + let last_loc = Procdesc.Node.get_loc (Procdesc.get_exit_node proc_desc) in + let message = F.asprintf "Leaked %a resource(s)" ResourceLeakDomain.pp post in + Reporting.log_error proc_desc err_log ~loc:last_loc ResourceLeakLabExercise + IssueType.lab_resource_leak message + (** Main function into the checker--registered in RegisterCheckers *) let checker ({InterproceduralAnalysis.proc_desc} as analysis_data) = diff --git a/infer/tests/codetoanalyze/cpp/biabduction/issues.exp b/infer/tests/codetoanalyze/cpp/biabduction/issues.exp index 90cc27b74..71fc1d3fb 100644 --- a/infer/tests/codetoanalyze/cpp/biabduction/issues.exp +++ b/infer/tests/codetoanalyze/cpp/biabduction/issues.exp @@ -100,10 +100,10 @@ codetoanalyze/cpp/biabduction/smart_ptr/unique_ptr_deref.cpp, unique_ptr::FP_res codetoanalyze/cpp/biabduction/smart_ptr/unique_ptr_deref.cpp, unique_ptr::FP_reset_ptr_deref_ok, 2, MEMORY_LEAK, CPP, ERROR, [start of procedure unique_ptr::FP_reset_ptr_deref_ok(),Skipping unique_ptr: method has no implementation,Skipping reset: method has no implementation] codetoanalyze/cpp/biabduction/smart_ptr/unique_ptr_deref.cpp, unique_ptr::FP_unique_ptr_move_deref_ok, 1, MEMORY_LEAK, CPP, ERROR, [start of procedure unique_ptr::FP_unique_ptr_move_deref_ok(),Skipping unique_ptr: method has no implementation] codetoanalyze/cpp/biabduction/smart_ptr/unique_ptr_deref.cpp, unique_ptr::unique_ptr_assign_deref_ok, 1, MEMORY_LEAK, CPP, ERROR, [start of procedure unique_ptr::unique_ptr_assign_deref_ok(),Skipping unique_ptr: method has no implementation] -codetoanalyze/cpp/biabduction/stack_escape/basic.cpp, basic_escape_local_bad, 3, STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure basic_escape_local_bad(),return from a call to basic_escape_local_bad] -codetoanalyze/cpp/biabduction/stack_escape/basic.cpp, basic_escape_param_bad, 0, STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure basic_escape_param_bad(),return from a call to basic_escape_param_bad] -codetoanalyze/cpp/biabduction/stack_escape/basic.cpp, escape_local_struct_member_bad, 3, STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure escape_local_struct_member_bad(),start of procedure EscapeTest,return from a call to EscapeTest::EscapeTest,return from a call to escape_local_struct_member_bad] -codetoanalyze/cpp/biabduction/static_local/nonstatic_local_bad.cpp, nonstatic_local_bad, 3, STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure nonstatic_local_bad(),return from a call to nonstatic_local_bad] +codetoanalyze/cpp/biabduction/stack_escape/basic.cpp, basic_escape_local_bad, 3, BIABD_STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure basic_escape_local_bad(),return from a call to basic_escape_local_bad] +codetoanalyze/cpp/biabduction/stack_escape/basic.cpp, basic_escape_param_bad, 0, BIABD_STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure basic_escape_param_bad(),return from a call to basic_escape_param_bad] +codetoanalyze/cpp/biabduction/stack_escape/basic.cpp, escape_local_struct_member_bad, 3, BIABD_STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure escape_local_struct_member_bad(),start of procedure EscapeTest,return from a call to EscapeTest::EscapeTest,return from a call to escape_local_struct_member_bad] +codetoanalyze/cpp/biabduction/static_local/nonstatic_local_bad.cpp, nonstatic_local_bad, 3, BIABD_STACK_VARIABLE_ADDRESS_ESCAPE, no_bucket, ERROR, [start of procedure nonstatic_local_bad(),return from a call to nonstatic_local_bad] codetoanalyze/cpp/biabduction/static_local/nonstatic_local_bad.cpp, nonstatic_local_caller, 2, DANGLING_POINTER_DEREFERENCE, no_bucket, ERROR, [start of procedure nonstatic_local_caller(),start of procedure nonstatic_local_bad(),return from a call to nonstatic_local_bad] codetoanalyze/cpp/biabduction/subtyping/cast_with_enforce.cpp, cast_with_enforce::cast_with_npe, 3, NULL_DEREFERENCE, B1, ERROR, [start of procedure cast_with_enforce::cast_with_npe(),start of procedure Base,return from a call to cast_with_enforce::Base::Base] codetoanalyze/cpp/biabduction/subtyping/dynamic_cast.cpp, dynamic__cast::rightPointerCast, 4, DIVIDE_BY_ZERO, no_bucket, ERROR, [start of procedure dynamic__cast::rightPointerCast(),start of procedure Derived,start of procedure Base,return from a call to dynamic__cast::Base::Base,return from a call to dynamic__cast::Derived::Derived,Taking true branch]