@ -6,6 +6,7 @@
* )
* )
open ! IStd
open ! IStd
module L = Die
type t =
type t =
| AnnotationReachability
| AnnotationReachability
@ -42,7 +43,7 @@ type support = NoSupport | Support | ExperimentalSupport | ToySupport
type cli_flags = { long : string ; deprecated : string list ; show_in_help : bool }
type cli_flags = { long : string ; deprecated : string list ; show_in_help : bool }
type config =
type config =
{ name : string
{ id : string
; support : Language . t -> support
; support : Language . t -> support
; short_documentation : string
; short_documentation : string
; cli_flags : cli_flags option
; cli_flags : cli_flags option
@ -52,7 +53,7 @@ type config =
(* support for languages should be consistent with the corresponding
(* support for languages should be consistent with the corresponding
callbacks registered . Or maybe with the issues reported in link
callbacks registered . Or maybe with the issues reported in link
with each analysis . Some runtime check probably needed . * )
with each analysis . Some runtime check probably needed . * )
let config checker =
let config _unsafe checker =
let supports_clang_and_java _ = Support in
let supports_clang_and_java _ = Support in
let supports_clang_and_java_experimental _ = ExperimentalSupport in
let supports_clang_and_java_experimental _ = ExperimentalSupport in
let supports_clang ( language : Language . t ) =
let supports_clang ( language : Language . t ) =
@ -66,7 +67,7 @@ let config checker =
in
in
match checker with
match checker with
| AnnotationReachability ->
| AnnotationReachability ->
{ name= " annotation reachability"
{ id= " annotation- reachability"
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation =
; short_documentation =
" the annotation reachability checker. Given a pair of source and sink annotation, e.g. \
" the annotation reachability checker. Given a pair of source and sink annotation, e.g. \
@ -77,7 +78,7 @@ let config checker =
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| Biabduction ->
| Biabduction ->
{ name = " biabduction "
{ id = " biabduction "
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation =
; short_documentation =
" the separation logic based bi-abduction analysis using the checkers framework "
" the separation logic based bi-abduction analysis using the checkers framework "
@ -85,7 +86,7 @@ let config checker =
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| BufferOverrunAnalysis ->
| BufferOverrunAnalysis ->
{ name= " buffer overrun analysis"
{ id= " buffer-overrun- analysis"
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation =
; short_documentation =
" internal part of the buffer overrun analysis that computes values at each program \
" internal part of the buffer overrun analysis that computes values at each program \
@ -94,35 +95,35 @@ let config checker =
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| BufferOverrunChecker ->
| BufferOverrunChecker ->
{ name= " buffer overrun checker"
{ id= " buffer-overrun- checker"
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation = " the buffer overrun analysis "
; short_documentation = " the buffer overrun analysis "
; cli_flags = Some { long = " bufferoverrun " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " bufferoverrun " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [ BufferOverrunAnalysis ] }
; activates = [ BufferOverrunAnalysis ] }
| ClassLoads ->
| ClassLoads ->
{ name= " Class loading analysis"
{ id= " class-loading- analysis"
; support = supports_java
; support = supports_java
; short_documentation = " Java class loading analysis "
; short_documentation = " Java class loading analysis "
; cli_flags = Some { long = " class-loads " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " class-loads " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| Cost ->
| Cost ->
{ name= " cost analysis"
{ id= " cost- analysis"
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation = " checker for performance cost analysis "
; short_documentation = " checker for performance cost analysis "
; cli_flags = Some { long = " cost " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " cost " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [ BufferOverrunAnalysis ] }
; activates = [ BufferOverrunAnalysis ] }
| Eradicate ->
| Eradicate ->
{ name = " eradicate "
{ id = " eradicate "
; support = supports_java
; support = supports_java
; short_documentation = " the eradicate @Nullable checker for Java annotations "
; short_documentation = " the eradicate @Nullable checker for Java annotations "
; cli_flags = Some { long = " eradicate " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " eradicate " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| FragmentRetainsView ->
| FragmentRetainsView ->
{ name= " fragment retains view"
{ id= " fragment-retains- view"
; support = supports_java
; support = supports_java
; short_documentation =
; short_documentation =
" detects when Android fragments are not explicitly nullified before becoming unreabable "
" detects when Android fragments are not explicitly nullified before becoming unreabable "
@ -130,7 +131,7 @@ let config checker =
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| ImmutableCast ->
| ImmutableCast ->
{ name= " immutable cast"
{ id= " immutable- cast"
; support = supports_java
; support = supports_java
; short_documentation =
; short_documentation =
" the detection of object cast from immutable type to mutable type. For instance, it will \
" the detection of object cast from immutable type to mutable type. For instance, it will \
@ -139,14 +140,14 @@ let config checker =
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| Impurity ->
| Impurity ->
{ name = " impurity "
{ id = " impurity "
; support = supports_clang_and_java_experimental
; support = supports_clang_and_java_experimental
; short_documentation = " [EXPERIMENTAL] Impurity analysis "
; short_documentation = " [EXPERIMENTAL] Impurity analysis "
; cli_flags = Some { long = " impurity " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " impurity " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [ Pulse ] }
; activates = [ Pulse ] }
| InefficientKeysetIterator ->
| InefficientKeysetIterator ->
{ name= " inefficient keyset iterator"
{ id= " inefficient-keyset- iterator"
; support = supports_java
; support = supports_java
; short_documentation =
; short_documentation =
" Check for inefficient uses of keySet iterator that access both the key and the value. "
" Check for inefficient uses of keySet iterator that access both the key and the value. "
@ -154,35 +155,35 @@ let config checker =
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| Linters ->
| Linters ->
{ name= " AST Language (AL) linters"
{ id= " al- linters"
; support = supports_clang
; support = supports_clang
; short_documentation = " syntactic linters "
; short_documentation = " syntactic linters "
; cli_flags = Some { long = " linters " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " linters " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| LithoRequiredProps ->
| LithoRequiredProps ->
{ name = " litho-required-props "
{ id = " litho-required-props "
; support = supports_java_experimental
; support = supports_java_experimental
; short_documentation = " [EXPERIMENTAL] Required Prop check for Litho "
; short_documentation = " [EXPERIMENTAL] Required Prop check for Litho "
; cli_flags = Some { long = " litho-required-props " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " litho-required-props " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| Liveness ->
| Liveness ->
{ name = " liveness "
{ id = " liveness "
; support = supports_clang
; support = supports_clang
; short_documentation = " the detection of dead stores and unused variables "
; short_documentation = " the detection of dead stores and unused variables "
; cli_flags = Some { long = " liveness " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " liveness " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| LoopHoisting ->
| LoopHoisting ->
{ name= " loop hoisting"
{ id= " loop- hoisting"
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation = " checker for loop-hoisting "
; short_documentation = " checker for loop-hoisting "
; cli_flags = Some { long = " loop-hoisting " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " loop-hoisting " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [ BufferOverrunAnalysis ; Purity ] }
; activates = [ BufferOverrunAnalysis ; Purity ] }
| NullsafeDeprecated ->
| NullsafeDeprecated ->
{ name = " nullsafe "
{ id = " nullsafe "
; support = ( fun _ -> NoSupport )
; support = ( fun _ -> NoSupport )
; short_documentation = " [RESERVED] Reserved for nullsafe typechecker, use --eradicate for now "
; short_documentation = " [RESERVED] Reserved for nullsafe typechecker, use --eradicate for now "
; cli_flags =
; cli_flags =
@ -193,7 +194,7 @@ let config checker =
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| PrintfArgs ->
| PrintfArgs ->
{ name= " printf args"
{ id= " printf- args"
; support = supports_java
; support = supports_java
; short_documentation =
; short_documentation =
" the detection of mismatch between the Java printf format strings and the argument types \
" the detection of mismatch between the Java printf format strings and the argument types \
@ -203,49 +204,49 @@ let config checker =
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| Pulse ->
| Pulse ->
{ name = " pulse "
{ id = " pulse "
; support = supports_clang_and_java_experimental
; support = supports_clang_and_java_experimental
; short_documentation = " [EXPERIMENTAL] memory and lifetime analysis "
; short_documentation = " [EXPERIMENTAL] memory and lifetime analysis "
; cli_flags = Some { long = " pulse " ; deprecated = [ " -ownership " ] ; show_in_help = true }
; cli_flags = Some { long = " pulse " ; deprecated = [ " -ownership " ] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| Purity ->
| Purity ->
{ name = " purity "
{ id = " purity "
; support = supports_clang_and_java_experimental
; support = supports_clang_and_java_experimental
; short_documentation = " [EXPERIMENTAL] Purity analysis "
; short_documentation = " [EXPERIMENTAL] Purity analysis "
; cli_flags = Some { long = " purity " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " purity " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [ BufferOverrunAnalysis ] }
; activates = [ BufferOverrunAnalysis ] }
| Quandary ->
| Quandary ->
{ name = " quandary "
{ id = " quandary "
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation = " the quandary taint analysis "
; short_documentation = " the quandary taint analysis "
; cli_flags = Some { long = " quandary " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " quandary " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| RacerD ->
| RacerD ->
{ name = " RacerD "
{ id = " RacerD "
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation = " the RacerD thread safety analysis "
; short_documentation = " the RacerD thread safety analysis "
; cli_flags = Some { long = " racerd " ; deprecated = [ " -threadsafety " ] ; show_in_help = true }
; cli_flags = Some { long = " racerd " ; deprecated = [ " -threadsafety " ] ; show_in_help = true }
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| ResourceLeakLabExercise ->
| ResourceLeakLabExercise ->
{ name= " resource leak lab exercise "
{ id= " resource-leak-lab "
; support = ( fun _ -> ToySupport )
; support = ( fun _ -> ToySupport )
; short_documentation = " "
; short_documentation = " "
; cli_flags = Some { long = " resource-leak " ; deprecated = [] ; show_in_help = false }
; cli_flags = Some { long = " resource-leak " ; deprecated = [] ; show_in_help = false }
; enabled_by_default = false
; enabled_by_default = false
; activates = [] }
; activates = [] }
| SIOF ->
| SIOF ->
{ name = " SIOF "
{ id = " SIOF "
; support = supports_clang
; support = supports_clang
; short_documentation = " the Static Initialization Order Fiasco analysis (C++ only) "
; short_documentation = " the Static Initialization Order Fiasco analysis (C++ only) "
; cli_flags = Some { long = " siof " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " siof " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| SelfInBlock ->
| SelfInBlock ->
{ name= " Self captured in block checker "
{ id= " self-in-block "
; support = supports_clang
; support = supports_clang
; short_documentation =
; short_documentation =
" checker to flag incorrect uses of when Objective-C blocks capture self "
" checker to flag incorrect uses of when Objective-C blocks capture self "
@ -253,21 +254,21 @@ let config checker =
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| Starvation ->
| Starvation ->
{ name= " Starvation analysis "
{ id= " starvation "
; support = supports_clang_and_java
; support = supports_clang_and_java
; short_documentation = " starvation analysis "
; short_documentation = " starvation analysis "
; cli_flags = Some { long = " starvation " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " starvation " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = true
; enabled_by_default = true
; activates = [] }
; activates = [] }
| TOPL ->
| TOPL ->
{ name = " TOPL "
{ id = " TOPL "
; support = supports_clang_and_java_experimental
; support = supports_clang_and_java_experimental
; short_documentation = " TOPL "
; short_documentation = " TOPL "
; cli_flags = Some { long = " topl " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " topl " ; deprecated = [] ; show_in_help = true }
; enabled_by_default = false
; enabled_by_default = false
; activates = [ Biabduction ] }
; activates = [ Biabduction ] }
| Uninit ->
| Uninit ->
{ name= " uninitialized variables "
{ id= " uninit "
; support = supports_clang
; support = supports_clang
; short_documentation = " checker for use of uninitialized values "
; short_documentation = " checker for use of uninitialized values "
; cli_flags = Some { long = " uninit " ; deprecated = [] ; show_in_help = true }
; cli_flags = Some { long = " uninit " ; deprecated = [] ; show_in_help = true }
@ -275,4 +276,16 @@ let config checker =
; activates = [] }
; activates = [] }
let get_name c = ( config c ) . name
let config c =
let config = config_unsafe c in
let is_illegal_id_char c = match c with 'a' .. 'z' | 'A' .. 'Z' | '-' -> false | _ -> true in
String . find config . id ~ f : is_illegal_id_char
| > Option . iter ~ f : ( fun c ->
L . die InternalError
" Illegal character '%c' in id: '%s'. Checker ids must be easy to pass on the command \
line . "
c config . id ) ;
config
let get_id c = ( config c ) . id