You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
5.5 KiB
145 lines
5.5 KiB
(*
|
|
* Copyright (c) 2013 - 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
|
|
|
|
(** Module for registering checkers. *)
|
|
|
|
module L = Logging
|
|
module F = Format
|
|
|
|
(* make sure SimpleChecker.ml is not dead code *)
|
|
let () = if false then let module SC = SimpleChecker.Make in ()
|
|
|
|
type callback_fun =
|
|
| Procedure of Callbacks.proc_callback_t
|
|
| DynamicDispatch of Callbacks.proc_callback_t
|
|
| Cluster of Callbacks.cluster_callback_t
|
|
|
|
type callback = callback_fun * Language.t
|
|
|
|
type checker = {name: string; active: bool; callbacks: callback list}
|
|
|
|
let all_checkers =
|
|
(* TODO (T24393492): the checkers should run in the order from this list.
|
|
Currently, the checkers are run in the reverse order *)
|
|
[ { name= "annotation reachability"
|
|
; active= Config.annotation_reachability
|
|
; callbacks= [(Procedure AnnotationReachability.checker, Language.Java)] }
|
|
; { name= "nullable checks"
|
|
; active= Config.check_nullable
|
|
; callbacks=
|
|
[ (Procedure NullabilityCheck.checker, Language.Clang)
|
|
; (Procedure NullabilityCheck.checker, Language.Java) ] }
|
|
; { name= "biabduction"
|
|
; active= Config.biabduction
|
|
; callbacks=
|
|
[ (Procedure Interproc.analyze_procedure, Language.Clang)
|
|
; (DynamicDispatch Interproc.analyze_procedure, Language.Java) ] }
|
|
; { name= "buffer overrun"
|
|
; active= Config.bufferoverrun
|
|
; callbacks=
|
|
[ (Procedure BufferOverrunChecker.checker, Language.Clang)
|
|
; (Procedure BufferOverrunChecker.checker, Language.Java) ] }
|
|
; { name= "crashcontext"
|
|
; active= Config.crashcontext
|
|
; callbacks= [(Procedure BoundedCallTree.checker, Language.Java)] }
|
|
; { name= "eradicate"
|
|
; active= Config.eradicate
|
|
; callbacks= [(Procedure Eradicate.callback_eradicate, Language.Java)] }
|
|
; { name= "fragment retains view"
|
|
; active= Config.fragment_retains_view
|
|
; callbacks=
|
|
[(Procedure FragmentRetainsViewChecker.callback_fragment_retains_view, Language.Java)] }
|
|
; { name= "immutable cast"
|
|
; active= Config.immutable_cast
|
|
; callbacks= [(Procedure ImmutableChecker.callback_check_immutable_cast, Language.Java)] }
|
|
; { name= "liveness"
|
|
; active= Config.liveness
|
|
; callbacks= [(Procedure Liveness.checker, Language.Clang)] }
|
|
; { name= "printf args"
|
|
; active= Config.printf_args
|
|
; callbacks= [(Procedure PrintfArgs.callback_printf_args, Language.Java)] }
|
|
; { name= "nullable suggestion"
|
|
; active= Config.suggest_nullable
|
|
; callbacks=
|
|
[ (Procedure NullabilitySuggest.checker, Language.Java)
|
|
; (Procedure NullabilitySuggest.checker, Language.Clang) ] }
|
|
; { name= "ownership"
|
|
; active= Config.ownership
|
|
; callbacks= [(Procedure Ownership.checker, Language.Clang)] }
|
|
; { name= "quandary"
|
|
; active= Config.quandary
|
|
; callbacks=
|
|
[ (Procedure JavaTaintAnalysis.checker, Language.Java)
|
|
; (Procedure ClangTaintAnalysis.checker, Language.Clang) ] }
|
|
; { name= "RacerD"
|
|
; active= Config.racerd
|
|
; callbacks=
|
|
[ (Procedure RacerD.analyze_procedure, Language.Clang)
|
|
; (Procedure RacerD.analyze_procedure, Language.Java)
|
|
; (Cluster RacerD.file_analysis, Language.Clang)
|
|
; (Cluster RacerD.file_analysis, Language.Java) ] }
|
|
(* toy resource analysis to use in the infer lab, see the lab/ directory *)
|
|
; { name= "resource leak"
|
|
; active= Config.resource_leak
|
|
; callbacks=
|
|
[ ( (* the checked-in version is intraprocedural, but the lab asks to make it
|
|
interprocedural later on *)
|
|
Procedure ResourceLeaks.checker
|
|
, Language.Java ) ] }
|
|
; {name= "litho"; active= Config.litho; callbacks= [(Procedure Litho.checker, Language.Java)]}
|
|
; {name= "SIOF"; active= Config.siof; callbacks= [(Procedure Siof.checker, Language.Clang)]}
|
|
; { name= "uninitialized variables"
|
|
; active= Config.uninit
|
|
; callbacks= [(Procedure Uninit.checker, Language.Clang)] }
|
|
; { name= "cost analysis"
|
|
; active= Config.cost
|
|
; callbacks= [(Procedure Cost.checker, Language.Clang); (Procedure Cost.checker, Language.Java)]
|
|
}
|
|
; { name= "Starvation analysis"
|
|
; active= Config.starvation
|
|
; callbacks=
|
|
[ (Procedure Starvation.analyze_procedure, Language.Java)
|
|
; (Cluster Starvation.reporting, Language.Java) ] } ]
|
|
|
|
|
|
let get_active_checkers () =
|
|
let filter_checker {active} = active in
|
|
List.filter ~f:filter_checker all_checkers
|
|
|
|
|
|
let register checkers =
|
|
let register_one {callbacks} =
|
|
let register_callback (callback, language) =
|
|
match callback with
|
|
| Procedure procedure_cb ->
|
|
Callbacks.register_procedure_callback language procedure_cb
|
|
| DynamicDispatch procedure_cb ->
|
|
Callbacks.register_procedure_callback ~dynamic_dispatch:true language procedure_cb
|
|
| Cluster cluster_cb ->
|
|
Callbacks.register_cluster_callback language cluster_cb
|
|
in
|
|
List.iter ~f:register_callback callbacks
|
|
in
|
|
List.iter ~f:register_one checkers
|
|
|
|
|
|
module LanguageSet = Caml.Set.Make (Language)
|
|
|
|
let pp_checker fmt {name; callbacks} =
|
|
let langs_of_callbacks =
|
|
List.fold_left callbacks ~init:LanguageSet.empty ~f:(fun langs (_, lang) ->
|
|
LanguageSet.add lang langs )
|
|
|> LanguageSet.elements
|
|
in
|
|
F.fprintf fmt "%s (%a)" name
|
|
(Pp.seq ~sep:", " (Pp.to_string ~f:Language.to_string))
|
|
langs_of_callbacks
|