infer-analyze(1)

πŸ“¦ version 1.3.0, in nixpkgs unstable

πŸ’… infer-analyze(1) β€” Infer Analysis πŸŽ€

okay so bestie, welcome to infer-analyze(1) β€” this is the manual page for the Infer Analysis tool, and we're gonna get through it together, no cap. Grab a snack, this one's a long read. πŸ“


✨ NAME ✨

infer-analyze β€” analyze the files captured by infer πŸ’–

like, infer already captured everything, and now this bad boy actually goes in and does the analyzing. iconic behavior honestly.


🌸 SYNOPSIS 🌸

infer analyze [options]
infer [options]

two ways to run it: you can be explicit with infer analyze, or you can just hit infer raw and let it do its thing. both slay. 🫢


πŸ¦‹ DESCRIPTION πŸ¦‹

Analyze the files captured in the project results directory and report.

that's it, that's the vibe. it takes what's in the results directory, analyzes it, and reports back to you. main character energy fr fr. ✨


πŸ‘‘ OPTIONS πŸ‘‘

okay this is the big one β€” there are so many options and we're listing every single one, no skipping, no summarizing. hydrate before you scroll. πŸ’œ

  • --annotation-reachability β€” Activates: annotation-reachability checker: Given pairs of source and sink annotations, e.g. @A and @B, this checker will warn whenever some method annotated with @A calls, directly or indirectly, another method annotated with @B. Besides the custom pairs, it is also possible to enable some built-in checks, such as @PerformanceCritical reaching @Expensive or @NoAllocation reaching new. It is also possible to model methods as if they were annotated, using regular expressions. This should also work in languages where there are no annotations. See flags starting with --annotation-reachability. (Conversely: --no-annotation-reachability)
  • --annotation-reachability-only β€” Activates: Enable annotation-reachability and disable all other checkers (Conversely: --no-annotation-reachability-only)
  • --bufferoverrun β€” Activates: bufferoverrun checker: InferBO is a detector for out-of-bounds array accesses. DEPRECATED: Use Pulse instead. (Conversely: --no-bufferoverrun)
heads up bestie: that one's DEPRECATED β€” use Pulse instead. don't come crying to me when it goes away 😭
  • --bufferoverrun-only β€” Activates: Enable bufferoverrun and disable all other checkers (Conversely: --no-bufferoverrun-only)
  • --changed-files-index file β€” Specify the file containing the list of source files from which reactive analysis should start. Source files should be specified relative to project root or be absolute
  • --config-gating β€” Activates: config-gating checker: Determines which config flags gate the execution of each line of code. (Conversely: --no-config-gating)
  • --config-gating-only β€” Activates: Enable config-gating and disable all other checkers (Conversely: --no-config-gating-only)
  • --config-impact-analysis β€” Activates: config-impact-analysis checker: [EXPERIMENTAL] Collects function that are called without config checks. (Conversely: --no-config-impact-analysis)
  • --config-impact-analysis-only β€” Activates: Enable config-impact-analysis and disable all other checkers (Conversely: --no-config-impact-analysis-only)
  • --continue-analysis β€” Activates: Continue the analysis after more targets are captured by --continue. The other analysis options should be given the same before. Not compatible with --reanalyze and --incremental-analysis. (Conversely: --no-continue-analysis)
compatibility tea: --continue-analysis does not play nice with --reanalyze or --incremental-analysis. keep them apart bestie πŸ™ˆ
  • --cost β€” Activates: cost checker: Computes the asymptotic complexity of functions with respect to execution cost or other user defined resources. Can be used to detect changes in the complexity with infer reportdiff. (Conversely: --no-cost)
  • --cost-only β€” Activates: Enable cost and disable all other checkers (Conversely: --no-cost-only)
  • --no-cost-suppress-func-ptr β€” Deactivates: Suppress printing function pointers in cost reports (Conversely: --cost-suppress-func-ptr)
  • --debug, -g β€” Activates: Debug mode (also sets --debug-level 2, --developer-mode, --print-buckets, --print-types, --reports-include-ml-loc, --no-only-cheap-debug, --trace-error, --write-html) (Conversely: --no-debug | -G)
  • --debug-level level β€” Debug level (sets --bo-debug level, --debug-level-analysis level, --debug-level-capture level):
    • 0: only basic debugging enabled
    • 1: verbose debugging enabled
    • 2: very verbose debugging enabled
  • --debug-level-analysis int β€” Debug level for the analysis. See --debug-level for accepted values.
  • --debug-level-capture int β€” Debug level for the capture. See --debug-level for accepted values.
  • --debug-level-report int β€” Debug level for the report. See --debug-level for accepted values.
  • --no-deduplicate β€” Deactivates: Apply issue-specific deduplication during analysis and/or reporting. (Conversely: --deduplicate)
  • --no-default-checkers β€” Deactivates: Default checkers: --static-constructor-stall-checker, --fragment-retains-view, --inefficient-keyset-iterator, --liveness, --parameter-not-null-checked, --pulse, --racerd, --self-in-block, --starvation, --swift-objc-nullability (Conversely: --default-checkers)
  • --detach-analysis-dependency β€” Activates: Detach analysis dependencies of checkers during the analysis, so that each checker triggers themselves only when analyzing a callee. This can save unnecessary analyses on the situation that NOT all of the captured data should be analyzed, e.g. --changed-files-index is given. (Conversely: --no-detach-analysis-dependency)
  • --dict-missing-key-var-block-list +string β€” Skip analyzing the variables in the dict-missing-key checker.
  • --files-to-analyze-index file β€” File containing a list of source files where analysis should start from. When used, the set of files given to this argument must be a subset of that passed to --changed-files-index (which must be specified).
important: if you use this, --changed-files-index is mandatory, and your file list has to be a subset of it. no exceptions πŸ’…
  • --no-fragment-retains-view β€” Deactivates: fragment-retains-view checker: Detects when Android fragments are not explicitly nullified before becoming unreachable. (Conversely: --fragment-retains-view)
  • --fragment-retains-view-only β€” Activates: Enable fragment-retains-view and disable all other checkers (Conversely: --no-fragment-retains-view-only)
  • --help β€” Show this manual
  • --help-format { auto | groff | pager | plain } β€” Show this help in the specified format. auto sets the format to plain if the environment variable TERM is "dumb" or undefined, and to pager otherwise.
  • --help-full β€” Show this manual with all internal options in the INTERNAL OPTIONS section
  • --impurity β€” Activates: impurity checker: Detects functions with potential side-effects. Same as "purity", but implemented on top of Pulse. ACTIVATES: pulse DEPRECATED: This checker is deprecated and will be removed in a future release. (Conversely: --no-impurity)
sad news: this one's DEPRECATED too and is getting yeeted in a future release. also lowkey note it ACTIVATES pulse as a side effect 🫢
  • --impurity-only β€” Activates: Enable impurity and disable all other checkers (Conversely: --no-impurity-only)
  • --impurity-report-immutable-modifications β€” Activates: Report modifications to immutable fields in the Impurity checker (Conversely: --no-impurity-report-immutable-modifications)
  • --incremental-analysis β€” Activates: Use incremental analysis for changed files. Not compatible with --reanalyze and --continue-analysis. Also sets --mark-unchanged-procs. (Conversely: --no-incremental-analysis)
  • --no-inefficient-keyset-iterator β€” Deactivates: inefficient-keyset-iterator checker: Check for inefficient uses of iterators that iterate on keys then lookup their values, instead of iterating on key-value pairs directly. (Conversely: --inefficient-keyset-iterator)
  • --inefficient-keyset-iterator-only β€” Activates: Enable inefficient-keyset-iterator and disable all other checkers (Conversely: --no-inefficient-keyset-iterator-only)
  • --invalidate-only β€” Activates: Remove any summaries from the results database that transitively depend on a changed procedure, then exit without doing any actual analysis. (Conversely: --no-invalidate-only)
  • --jobs, -j int β€” Run the specified number of analysis jobs simultaneously. Defaults to the minimum value of the max_jobs argument and the number of CPUs.
  • --keep-going β€” Activates: Keep going when the analysis or capture encounter a failure (Conversely: --no-keep-going)
  • --lineage β€” Activates: lineage checker: Computes a dataflow graph (Conversely: --no-lineage)
  • --lineage-only β€” Activates: Enable lineage and disable all other checkers (Conversely: --no-lineage-only)
  • --litho-required-props β€” Activates: litho-required-props checker: Checks that all non-optional @Props have been specified when constructing Litho components. (Conversely: --no-litho-required-props)
  • --litho-required-props-only β€” Activates: Enable litho-required-props and disable all other checkers (Conversely: --no-litho-required-props-only)
  • --no-liveness β€” Deactivates: liveness checker: Detection of dead stores and unused variables. (Conversely: --liveness)
  • --liveness-ignored-constant +string β€” List of integer constants to be ignored by liveness analysis
  • --liveness-only β€” Activates: Enable liveness and disable all other checkers (Conversely: --no-liveness-only)
  • --log-missing-deps β€” Activates: Log analysis dependencies that cannot be found. (Conversely: --no-log-missing-deps)
  • --loop-hoisting β€” Activates: loop-hoisting checker: Detect opportunities to hoist function calls that are invariant outside of loop bodies for efficiency. DEPRECATED: This checker is deprecated and will be removed in a future release. (Conversely: --no-loop-hoisting)
another one bites the dust: DEPRECATED, getting removed in a future release 😭
  • --loop-hoisting-only β€” Activates: Enable loop-hoisting and disable all other checkers (Conversely: --no-loop-hoisting-only)
  • --max-jobs int β€” Maximum number of analysis jobs running simultaneously. Experiments show current best value is 40 jobs.
fun fact bestie: experiments say the current best value is 40 jobs. not 39, not 41. forty. periodt.
  • --memtrace-analysis-profiling β€” Activates: Generate OCaml analysis allocation traces in infer-out/memtrace. (Conversely: --no-memtrace-analysis-profiling)
  • --memtrace-sampling-rate float β€” Sampling rate for Memtrace allocation profiling. Default is 1e-6.
  • --modeled-expensive json β€” Matcher or list of matchers for methods that should be considered expensive by the performance critical checker.
  • --multicore β€” Activates: [EXPERIMENTAL] uses multi-threading for analysis, currently partially or not implemented. (Conversely: --no-multicore)
experimental alert: this is partially or not implemented as of right now, so like… temper your expectations bestie 🫢
  • --never-returning-null json β€” [Java only, all analyses] Matcher or list of matchers for functions that never return null.
  • --noescaping-function-list +string β€” Useful for the check CXX_REF_CAPTURED_IN_BLOCK. It declares a list of functions that take blocks as arguments that are no escaping but we cannot annotate them accordingly.
  • --objc-block-execution-macro string β€” Macro for executing Objective-C blocks safely.
  • --ondemand-callchain-limit int β€” If enabled, the number of consecutive recursive ondemand call is bounded

okay that's the end of part one bestie, drink some water β€” more is coming and we are NOT done πŸ’…βœ¨

  • --ondemand-recursion-restart-limit int β€” okay so this one is about keeping mutual recursion cycles deterministic πŸ”. When the analysis hits a cycle of mutually recursive functions, it might restart the analysis of the entire cycle from a deterministic place so the output doesn't wiggle around. But if the mutual-recursion graph is more complicated than a simple cycle, that could mean a lot of restarts before it finds the "right" procedure to start from 😭. This flag caps how many restarts happen before it just gives up and analyzes the cycle as-is. Periodt.
  • --no-parameter-not-null-checked β€” Deactivates the parameter-not-null-checked checker: an Objective-C-specific analysis that detects when a block parameter is used before it's been checked for null πŸ™ˆ. (Conversely: --parameter-not-null-checked)
  • --parameter-not-null-checked-only β€” Activates: enable parameter-not-null-checked and disable all other checkers πŸ’…. (Conversely: --no-parameter-not-null-checked-only)
  • --print-active-checkers β€” Activates: print out the active checkers before the analysis even starts, so you know what's about to run πŸ‘‘. (Conversely: --no-print-active-checkers)
  • --print-logs β€” Activates: also log messages to stdout and stderr πŸ“. (Conversely: --no-print-logs)
  • --procs-to-analyze-index file β€” Specify the file containing an Sexp representing a list of pairs of procedures and specializations to analyze 🎯. Lowkey important: only works with the restart scheduler.
  • --progress-bar-style { auto | plain | multiline } β€” the vibe of your progress bar 🌈. auto picks multiline if you're connected to a tty, otherwise plain. That's it, that's the whole thing.
  • --project-root,-C dir β€” Specify the root directory of the project πŸ“.
  • --no-pulse β€” Deactivates the pulse checker: the general-purpose memory and value analysis engine πŸ«€. (Conversely: --pulse)
  • --pulse-only β€” Activates: enable pulse and disable all other checkers ✨. (Conversely: --no-pulse-only)
  • --purity β€” Activates the purity checker: detects pure (side-effect-free) functions 🧚. It's a different implementation of "impurity". DEPRECATED: this checker is deprecated and will be removed in a future release πŸ’€. (Conversely: --no-purity)
  • --purity-only β€” Activates: enable purity and disable all other checkers. (Conversely: --no-purity-only)
  • --qualified-cpp-name-block-list +string β€” Skip analyzing the procedures under the qualified cpp type name 🚫.
  • --quiet,-q β€” Activates: do not print anything on standard output 🀫. (Conversely: --no-quiet | -Q)
  • --no-racerd β€” Deactivates the racerd checker: thread safety analysis 🧡. (Conversely: --racerd)
  • --racerd-only β€” Activates: enable racerd and disable all other checkers. (Conversely: --no-racerd-only)
  • --reactive,-r β€” Activates: reactive mode, where the analysis starts from the files captured since the infer command started πŸ¦‹. (Conversely: --no-reactive | -R)
  • --reactive-capture β€” Activates: reactive capture, where capture and analysis are interleaved πŸ”₯. Heads up: currently this flag will only make the analysis generate a list of type names that were not found in the global tenv. And rn the feature is only available for the Hack frontend, iykyk. (Conversely: --no-reactive-capture)
  • --no-report β€” Deactivates: run the reporting phase once the analysis has completed. (Conversely: --report)
  • --report-force-relative-path β€” Activates: force converting an absolute path to a relative path to the root directory πŸ›€οΈ. (Conversely: --no-report-force-relative-path)
  • --results-dir,-o dir β€” Write results and internal files in the specified directory πŸ“‚.
  • --scope-leakage β€” Activates the scope-leakage checker: the Java/Kotlin checker that takes into account a set of "scope" annotations and a must-not-hold relation over those scopes πŸ”. It raises an alarm if there's a field access path from object A to object B, with respective scopes SA and SB, such that must-not-hold(SA, SB). Yeah. (Conversely: --no-scope-leakage)
  • --scope-leakage-only β€” Activates: enable scope-leakage and disable all other checkers. (Conversely: --no-scope-leakage-only)
  • --no-self-in-block β€” Deactivates the self-in-block checker: an Objective-C-specific analysis to detect when a block captures self πŸͺž. (Conversely: --self-in-block)
  • --self-in-block-only β€” Activates: enable self-in-block and disable all other checkers. (Conversely: --no-self-in-block-only)
  • --shrink-analysis-db β€” Activates: after analysis, delete analysis summaries (but not report summaries) and vacuum the analysis database 🧹. (Conversely: --no-shrink-analysis-db)
  • --sil-validation β€” Activates the sil-validation checker: it validates that all SIL instructions in all procedure bodies conform to a (front-end specific) subset of SIL βœ…. (Conversely: --no-sil-validation)
  • --sil-validation-only β€” Activates: enable sil-validation and disable all other checkers. (Conversely: --no-sil-validation-only)
  • --siof β€” Activates the siof checker: catches Static Initialization Order Fiascos in C++, which can lead to subtle, compiler-version-dependent errors 😱. DEPRECATED: this checker is deprecated and will be removed in a future release πŸ’€. (Conversely: --no-siof)
  • --siof-only β€” Activates: enable siof and disable all other checkers. (Conversely: --no-siof-only)
  • --sqlite-cache-size int β€” SQLite cache size, in pages if it's positive or kB if it's negative πŸ—„οΈ. It follows the format of the corresponding SQLite PRAGMA.
  • --sqlite-lock-timeout int β€” Timeout for SQLite results database operations, in milliseconds ⏱️.
  • --sqlite-max-blob-size int β€” Maximum blob/string size for data written in SQLite πŸ“¦.
  • --sqlite-mmap-size int β€” Size of the memory map for mmaped SQLite databases; a zero value disables memory mapping πŸ—ΊοΈ.
  • --sqlite-page-size int β€” SQLite page size in bytes β€” must be a power of two between 512 and 65536 πŸ”’.
  • --no-starvation β€” Deactivates the starvation checker: detects various kinds of situations when no progress is being made because of concurrency errors 🍽️. (Conversely: --starvation)
  • --starvation-only β€” Activates: enable starvation and disable all other checkers. (Conversely: --no-starvation-only)
  • --no-static-constructor-stall-checker β€” Deactivates the static-constructor-stall-checker checker: detects if dispatch_once is called from a static constructor 🧊. (Conversely: --static-constructor-stall-checker)
  • --static-constructor-stall-checker-only β€” Activates: enable static-constructor-stall-checker and disable all other checkers. (Conversely: --no-static-constructor-stall-checker-only)
  • --no-swift-objc-nullability β€” Deactivates the swift-objc-nullability checker: detects missing nullability annotations in Objective-C methods called from Swift, which can lead to runtime crashes via Implicitly Unwrapped Optionals πŸ’₯. (Conversely: --swift-objc-nullability)
  • --swift-objc-nullability-only β€” Activates: enable swift-objc-nullability and disable all other checkers. (Conversely: --no-swift-objc-nullability-only)
  • --timeout float β€” the time after which any checker should give up analysing the current function or method, in seconds ⏳. Defaults to 120 seconds.
  • --top-longest-proc-duration-size int β€” Number of procedures for which we track longest analysis duration info πŸ“Š.
  • --topl β€” Activates the topl checker: detects errors based on user-provided state machines describing temporal properties over multiple objects πŸ€–. Also ACTIVATES: pulse. (Conversely: --no-topl)
  • --topl-only β€” Activates: enable topl and disable all other checkers. (Conversely: --no-topl-only)
  • --write-html β€” Activates: produce html debug output for the analyses in infer-out/captured 🌐. This shows the abstract state of all analyses at each program point in the source code. Each captured source file has its own html page. This HTML file contains the source file, and at each line of the file there are links to the nodes of the control flow graph of Infer's translation of that line of code into its intermediate representation (SIL). This way it's possible to see what the translation is, and the details of the symbolic execution on each node. Kind of iconic ngl πŸ‘‘. (Conversely: --no-write-html)
  • --xcode-isysroot-suffix string β€” Specify the suffix of the Xcode isysroot directory, to avoid absolute paths in tests 🍎.

✨ ANALYSIS SCHEDULER OPTIONS ✨

  • --analysis-schedule-file path β€” the file where an analysis schedule is stored πŸ—“οΈ. The default is infer-out/analysis_dependency_graph.
  • --replay-analysis-schedule β€” Activates: replay the analysis schedule stored in --replay-analysis-schedule-file, which should analyze the procedures in the same order as the previous analysis πŸ”. This should drastically limit non-determinism in the results, and also prevent repeated work, leading to a faster second analysis. Big win. Only works if a previous analysis has just run on the same code, so don't get cute with it 🫢. (Conversely: --no-replay-analysis-schedule)
  • --replay-ondemand-should-error β€” Activates: [debug] whether triggering the analysis of a procedure via ondemand should log an error when replaying an analysis schedule with --replay-analysis-schedule πŸ›. Enable this when replaying the same analysis on the same capture data to debug cases where dependencies that were recorded are insufficient. (Conversely: --no-replay-ondemand-should-error)
  • --scheduler { file | restart | callgraph } β€” specify the scheduler used for the analysis phase 🧠:
    • file: schedules one job per file
    • callgraph: schedules one job per procedure, following the syntactic call graph. Usually faster than "file".
    • restart: schedules one job per procedure, using locking to try and avoid duplicate work between different analysis processes and thus performs generally better on high parallelism.
  • --store-analysis-schedule β€” Activates: store the analysis schedule for later replay, honoring --replay-analysis-schedule-file if present πŸ’Ύ. This can be useful to store a schedule done with one version of infer to load with another version of infer. That said β€” no cap β€” there is no guarantee infer will be able to load the previous schedule, but using this mechanism gives a higher chance of success compared with having to read the previous results database successfully, since fewer datatypes are involved. (Conversely: --no-store-analysis-schedule)

🌈 ANDROID OPTIONS 🌈

  • --android-view-class-list +string β€” a class C is considered a view when it has a supertype that matches one of these classes πŸ€–πŸ’–. The default is [android.view.View].

πŸ’₯ BUFFER OVERRUN OPTIONS πŸ’₯

okay so the buffer-overrun checker has ✨opinions✨ and these are the knobs, bestie. every single one, no skips, no cap.

  • --no-bo-assume-void β€” turns OFF the bit where we assume void type for record fields that aren't in the type environment πŸ’€ (flip it back on with --bo-assume-void)
  • --no-bo-bottom-as-default β€” turns OFF using bottom as a default value instead of unknown 🫢 (flip it back with --bo-bottom-as-default)
  • --bo-context-sensitive-allocsites β€” turns ON the assumption that different calls to the same function that creates an allocsite give you different allocsites imported to the caller πŸ‘‘ (off-ramp: --no-bo-context-sensitive-allocsites)
  • --bo-debug int β€” debug level for the buffer-overrun checker, ranges 0-4 πŸ”
  • --bo-exit-frontend-gener-vars β€” turns ON putting frontend-generated variables out of scope when they're listed in the exit scope instruction 🧚 (reverse mode: --no-bo-exit-frontend-gener-vars)
  • --bo-field-depth-limit int β€” the limit on field depth of abstract location in the buffer-overrun checker πŸ“
  • --bo-max-cfg-size int β€” CFGs bigger than the max size get skipped in buffer overrun analysis 🚫
  • --bo-sound-unknown-sets-join β€” turns ON "join with an unknown set always results in an unknown set". when it's disabled, an unknown set behaves as bot 😭 (the other direction: --no-bo-sound-unknown-sets-join)

🌈 CLANG OPTIONS 🌈

clang frontend settings, and honestly? iconic behaviour. let's go one by one.

  • --clang-compound-literal-init-limit int β€” the limit past which initializing compound types (structs and arrays) stops being done element by element, and instead uses a builtin function that each analysis has to model πŸŽ€
  • --cxx-scope-guards json β€” specify the scope guard classes that can be read only by destructors without getting reported as dead stores πŸ’…
  • --dynamic-dispatch-json-file-path path β€” the dynamic dispatch file path to get the JSON used for method name substitution πŸ¦‹
  • --inline-func-pointer-for-testing string β€” enables substituting global function pointers used for testing with the real function calls in the clang frontend. pass the prefix used to build the global function pointers used for testing πŸ§ͺ
  • --liveness-block-list-var-regex string β€” give a regular expression for variable names that get ignored when reporting dead stores πŸ™ˆ
  • --liveness-dangerous-classes json β€” specify classes where the destructor should be ignored when computing liveness. in other words: assignment to variables of these types (or common wrappers around these types such as unique_ptr<type>) will count as dead stores when the variables aren't read explicitly by the program 😳
  • --lock-model json β€” specify custom lock models for starvation analysis πŸ”’ example for pthreads (already included in infer):
[{"lock":["pthread_mutex_lock"],"unlock":["pthread_mutex_unlock"]}]
  • --pulse-model-unreachable +string β€” methods to be modeled as unreachable πŸ‘»
  • --pulse-unsafe-malloc β€” turns ON assuming that malloc(3) never returns null. living dangerously, love that for us πŸ”₯ (undo with --no-pulse-unsafe-malloc)

πŸ“ ERLANG OPTIONS πŸ“

  • --erlang-list-unfold-depth int β€” unfold Erlang lists up to depth int πŸ“š
  • --no-erlang-reliability β€” turns OFF analyzing crashing executions. heads up bestie, this flag affects BOTH capture and analysis: at capture time it encodes Erlang specs; at (Pulse) analysis time it models Erlang exceptions (builtin or OTP ones) πŸ’€ (flip back on with --erlang-reliability)

πŸ‘‘ JAVA OPTIONS πŸ‘‘

java time!! svgdhjsdf but fr these are all useful, keep reading.

  • --no-annotation-reachability-apply-superclass-annotations β€” turns OFF applying annotations from superclasses and interfaces also on methods that are NOT overridden from the superclass or interface πŸ™… (flip with --annotation-reachability-apply-superclass-annotations)
  • --annotation-reachability-check-loops β€” turns ON highlighting callsites in the trace that are nested in some loop πŸ” (off: --no-annotation-reachability-check-loops)
  • --annotation-reachability-custom-models json β€” use regular expressions to treat methods as if they were annotated ✨ the format is a map from annotations to objects with an "allow" and "block" field, which are both lists of regular expressions. a method is treated as annotated if any matcher in the allow list matches AND none of the matchers in the block list matches. if there are only "allow" matchers, a list can be given instead of the object. examples, exactly as they come:
Example 1: {"Annotation": ["com\\.Myclass\\.foo.*"]}
Example 2: {"Annotation": {"allow": ["foo.*"], "block": ["foobar"]}}
  • --annotation-reachability-custom-pairs json β€” specify custom sources/sinks, and optionally sanitizers, for the annotation reachability checker πŸ’– the optional "minimize_sinks" (default: true) and "minimize_sources" (default: false) flags control path minimization. when "minimize_sinks" is true, paths where a prefix is also a source-to-sink path are not reported. for example, if there's a source() -> sink1() -> sink2() path then only source() -> sink1() will be reported βœ‚οΈ when "minimize_sources" is true, paths where a suffix is also a source-to-sink path are not reported. for example, if there's a source1() -> source2() -> sink() path then only source2() -> sink() will be reported βœ‚οΈ example format: for custom annotations com.my.annotation.{Source1,Source2,Sink1,Sanitizer1}
{ "sources" : ["Source1", "Source2"], "sinks" : ["Sink1"],
"sanitizers": ["Sanitizer1"], "minimize_sources": true,
"minimize_sinks": false }
  • --annotation-reachability-expensive β€” turns ON checking if methods annotated with @PerformanceCritical can call expensive methods (annotated @Expensive or modeled, with annotation reachability checker) πŸ’Έ (off: --no-annotation-reachability-expensive)
  • --annotation-reachability-no-allocation β€” turns ON checking if methods annotated with @NoAllocation can allocate (with annotation reachability checker) 🚫 (off: --no-annotation-reachability-no-allocation)
  • --annotation-reachability-report-source-and-sink β€” turns ON reporting methods that are marked as both a source AND a sink at the same time 🎭 (off: --no-annotation-reachability-report-source-and-sink)
  • --external-java-packages +prefix β€” specify a list of Java package prefixes for external Java packages. if set, the analysis won't report non-actionable warnings on those packages 🀫
  • --java-version int β€” the version of Java being used. set it to your Java version if mvn is failing πŸ”§

πŸ¦‹ LINEAGE OPTIONS πŸ¦‹

  • --no-lineage-dedup β€” turns OFF attempting to print each entity at most once in JSON output. that's the default, btw. the ONLY reason you'd wanna turn this off is to make hash collisions more visible β€” like, cases where distinct entities get assigned the same ID πŸ‘€ (flip back with --lineage-dedup)
  • --lineage-field-depth int β€” [EXPERIMENTAL] maximal field depth sensitivity for lineage analysis. 0 makes the analysis field insensitive πŸ•³οΈ
  • --lineage-field-max-cfg-size int β€” if set, field sensitivity is disabled on larger CFGs πŸ“
  • --lineage-field-width int β€” [EXPERIMENTAL] maximal width of structures for field-sensitive lineage analysis. structures with a higher number of fields get smashed into a single element πŸ’₯ 0 makes the analysis field insensitive.
  • --lineage-include-builtins β€” turns ON including call/return edges to/from procedures that model primitive Erlang operations, such as constructing a list πŸ“ (off: --no-lineage-include-builtins)
  • --lineage-json-report β€” turns ON the lineage report in JSON format πŸ—‚οΈ (off: --no-lineage-json-report)
  • --lineage-keep-temporaries β€” turns ON this: normally, lineage summaries don't mention temporary variables introduced while compiling the high-level code to Infer's IR (intermediate representation). if this option is enabled, then the lineage graph produced corresponds to Infer's IR 🧬 (off: --no-lineage-keep-temporaries)
  • --lineage-max-cfg-size int β€” if set, larger CFGs are skipped 🚫
  • --no-lineage-prevent-cycles β€” turns OFF this: [EXPERIMENTAL] if given, Lineage will not stop traversing the fields of a variable when it notices recursive types (that is, a sub-field having the same type as one of its "ancestors") πŸ”„ (flip with --lineage-prevent-cycles)
  • --lineage-seed int β€” set the random seed used for hashing. various entities that get reported need unique identifiers, and to generate these unique identifiers in a distributed way without communication, we use hashing. if you're unlucky and get collisions, you can try a different seed 🎲
  • --lineage-variant-width int β€” maximal width of variant types for lineage analysis. a variant type is the type of a variable whose value is within a statically known atom set. the width of the type is the cardinal of that atom set πŸ”’

πŸ’œ PULSE CHECKER OPTIONS πŸ’œ

  • --log-pulse-coverage β€” turns ON logging precisely where coverage stops, at the end of file stats/stats.txt πŸ“Š (off: --no-log-pulse-coverage)
  • --log-pulse-disjunct-increase-after-model-call β€” turns ON logging which model increased the current number of Pulse disjuncts πŸ•΅οΈ (off: --no-log-pulse-disjunct-increase-after-model-call)
  • --pulse-cut-to-one-path-procedures-pattern string β€” regex of methods for which Pulse will only explore one path πŸ›€οΈ can be used on pathologically large procedures to prevent too-big states from being produced.
  • --pulse-eternal β€” turns ON [EXPERIMENTAL] the latest iteration of the non-termination loop prover based on the UNTER under-approximate theory ♾️ (off: --no-pulse-eternal)
  • --pulse-inline-global-init-func-pointer β€” turns ON inlining the initializer of global variables that are of type function pointer in Pulse πŸ”— (off: --no-pulse-inline-global-init-func-pointer)
  • --pulse-log-summary-count β€” turns ON logging the number of summaries (grouped by summary kind) for each analyzed procedure in Pulse πŸ“‹ results go in JSON files under a 'pulse' subdirectory, one corresponding to each analysis job. note that when joining the files, deduplication might be needed πŸ‘€ (off: --no-pulse-log-summary-count)
  • --pulse-max-cfg-size int β€” CFGs larger than the max size are skipped in Pulse 🚫
  • --pulse-max-disjuncts int β€” stop exploring new paths after int disjunctions in the domain βœ‹
  • --pulse-max-heap int β€” give up analysing a procedure if the number of words in the heap exceeds this limit 😡 intended use: avoid OutOfMemory crashes.
  • --pulse-model-abort +string β€” methods that should be modelled as abort in Pulse πŸ›‘
  • --pulse-model-alloc-pattern string β€” a regex of methods that Pulse should treat as allocs πŸ’– like, "these ones make new stuff, bestie."
  • --pulse-model-cheap-copy-type regex β€” regex of methods that are cheap to copy in Pulse. lowkey free, cost-wise πŸŽ€
  • --pulse-model-cheap-copy-type-list +regex β€” same vibe as above (methods that are cheap to copy in Pulse), just as a list. add away ✨
  • --pulse-model-deep-release-pattern string β€” regex of methods Pulse should model as a deep release, meaning it awaits all unawaited values reachable from its arguments. it's giving "clean up EVERYTHING" 🧹
  • --pulse-model-free-pattern string β€” regex of methods that should be modelled as wrappers to free(3) in Pulse. the pointer being freed has to be the first argument of the function. you only need this if the wrapper's code isn't visible to infer, or if Pulse somehow just doesn't get it (like when the call is dispatched to global function pointers). iykyk 🫢
  • --pulse-model-malloc-pattern string β€” regex of methods modelled as wrappers to malloc(3) in Pulse. size to allocate = first argument of the function. see --pulse-model-free-pattern for more info πŸ’…
  • --pulse-model-realloc-pattern string β€” regex of methods modelled as wrappers to realloc(3) in Pulse. pointer to reallocate = first argument, new size = second argument. again, peep --pulse-model-free-pattern for the deets 🌸
  • --pulse-model-release-pattern string β€” regex of methods that should be modelled as release in Pulse πŸ¦‹
  • --pulse-model-return-first-arg string β€” regex of methods modelled as returning the first argument in Pulse, in terms of the source language semantics. languages supported: Java, C, Objective-C ✨
  • --pulse-model-return-nonnull string β€” regex of methods modelled as returning non-null in Pulse πŸ‘‘
  • --pulse-model-return-nonnull-list +string β€” same thing (methods modelled as returning non-null in Pulse), as a list πŸ’œ
  • --pulse-model-return-nullable string β€” regex of methods modelled as returning nullable values in Pulse πŸ™ˆ
  • --pulse-model-return-nullable-list +string β€” the list version of methods modelled as returning nullable values in Pulse ⭐
  • --pulse-model-return-this string β€” regex of methods modelled as returning the this or self argument of an instance method in Pulse. languages supported: Java, Objective-C πŸ’… main character returns herself, honestly.
  • --pulse-model-returns-copy-pattern string β€” regex of methods modelled as creating copies in Pulse πŸŽ€
  • --pulse-model-skip-pattern string β€” regex of methods modelled as "skip" in Pulse. not today, bestie πŸ’€
  • --pulse-model-skip-pattern-list +string β€” the list version of methods modelled as "skip" in Pulse 🌈
  • --pulse-model-transfer-ownership +string β€” methods modelled as transferring memory ownership in Pulse. accepted formats are method or namespace::method πŸ”₯
  • --pulse-model-unknown-pure +string β€” regex of methods modelled as unknown pure in Pulse 🌸
  • --pulse-models-for-erlang +path β€” provide custom models for Erlang in JSON files or SQLite3. files must end with .json or .db respectively. if you hand it a directory path, the subdirectories get explored and names have to follow that same convention. SQLite3 format is preferable when you're providing a large number of models, because they'll be internally indexed by mfa 🧚

The JSON format is [SelectorBehavior, ...] where:

SelectorBehavior := {"selector": Selector, "behavior": Behavior}
Selector := ["MFA", {
  "module": "<module_name>",
  "function": "<function_name>",
  "arity": <arity_int>
}]
Behavior := ReturnValue | ArgumentsReturnList
 - ReturnValue models return regardless of the arguments
 - ArgumentsReturnList maps arguments to return values
ReturnValue := ["ReturnValue", ErlangValue]
ArgumentsReturnList :=
  ["ArgumentsReturnList", [ArgumentsReturn, ...]]
ArgumentsReturn :=  {
  "arguments": [ErlangValue, ...],
  "return": ErlangValue
}
ErlangValue := ["Atom", "<atom_name>"]
  | ["IntLit", "<integer_value>"]
  | ["List", [ErlangValue, ...]
  | ["Tuple", [ErlangValue, ...]
  | null
ErlangValue = null is to represent nondeterministic value

The SQLite3 format is a DB with this schema:

CREATE TABLE models(
  "mfa" TEXT,
  "behavior" TEXT
);
  • mfa is module:function/arity, e.g. "mymod:f/0"
  • behavior is a JSON Behavior (see above)
  • --no-pulse-nullsafe-report-npe β€” deactivates reporting null dereference issues on files marked @Nullsafe. (conversely: --pulse-nullsafe-report-npe) 🫢
  • --pulse-nullsafe-report-npe-as-separate-issue β€” activates reporting null dereference issues on files marked @Nullsafe as a separate NULLPTR_DEREFERENCE_IN_NULLSAFE_CLASS issue type. (conversely: --no-pulse-nullsafe-report-npe-as-separate-issue) ✨
  • --pulse-over-approximate-reasoning β€” activates [EXPERIMENTAL] over-approximate reasoning layered on top of the under-approximate, disjunctive reasoning of Pulse. (conversely: --no-pulse-over-approximate-reasoning) πŸ”₯ she's experimental, she's extra, she's doing the most.
  • --pulse-recency-limit int β€” max number of array elements and structure fields to keep track of for a given address πŸ’€ literally a memory budget for your memory budget.
  • --pulse-retain-cycle-blocklist-pattern string β€” skip reporting retain cycles that include an expression matching this pattern. super useful when devs use naming conventions to signal that certain variables are expected to be part of a retain cycle πŸŽ€
  • --pulse-skip-procedures regex β€” regex of procedures that Pulse should not analyze. bye bestie πŸ‘‹
  • --pulse-specialization-iteration-limit int β€” max number of iterative summary specializations at each call site πŸ¦‹
  • --pulse-specialization-limit int β€” max number of summary specializations by procedure πŸ’œ
  • --pulse-taint-config +path β€” path to a taint analysis config file, or a directory full of such files. this file can define --pulse-taint-sources, --pulse-taint-sanitizers, --pulse-taint-propagators, --pulse-taint-sinks, --pulse-taint-policies, and --pulse-taint-data-flow-kinds 🌸

If you give it a directory path, the config files must have the .json extension. any other file gets ignored, no cap. subdirectories will be explored and must follow the same convention ✨

  • --pulse-taint-data-flow-kinds json β€” specify which taint kinds should be used for data flow reporting only. if a source has such a kind, only data flows to sinks which originate at the source get reported. if a sink has such a kind, only sensitive data flows to the sink get reported πŸ‘‘
  • --no-pulse-taint-follow-field-accesses β€” deactivates specifying whether taint analysis should follow field accesses when propagating taints. (conversely: --pulse-taint-follow-field-accesses) 🫢
  • --pulse-taint-opaque-files +path β€” specify files that should be treated as opaque for taint analysis, making sure that procedures belonging to these files are always free of any potential taint flows πŸ™ˆ like, nothing to see here, move along.
  • --pulse-taint-policies json β€” a description of which taint flows should be reported, following this JSON format:
{ "short_description": "<a short description of the issue>",
  "taint_flows": [{ "source_kinds": [<kinds>],
                    "sink_kinds": [<kinds>],
                    "sanitizer_kinds": [<kinds>] }],
  "exclude_in": [<paths>],
  "exclude_matching": [<regexps>]
}

where <kinds> are specified in the taint source/sanitizer/sink matchers (see --pulse-taint-sources). the fields "sanitizer_kinds", "exclude_in" and "exclude_matching" are optional (assumed to be empty), and a single policy can specify several taint flows using a list πŸ“‹

this policy is always enabled:

{ "short_description": "...",
  "taint_flows": [{ "source_kinds": ["Simple"],
                    "sink_kinds": ["Simple"],
                    "sanitizer_kinds": ["Simple"]  }]
}
  • --pulse-taint-propagators json β€” quick way to specify simple propagators as JSON objects. see --pulse-taint-sources for the fields format documentation ✨
  • --pulse-taint-sanitizers json β€” quick way to specify simple sanitizers as JSON objects. see --pulse-taint-sources for the fields format documentation 🧼
  • --pulse-taint-short-traces β€” activates cutting off taint traces as soon as a tainted value flows into a sink πŸ”₯ this matters when the sink itself calls other sinks of the same kind, and as long as the value flows from call to call, without this flag the trace would include the whole chain of calls. (conversely: --no-pulse-taint-short-traces)
  • --pulse-taint-sinks json β€” quick way to specify simple sinks as JSON objects. see --pulse-taint-sources for the fields format documentation πŸ•³οΈ
  • --pulse-taint-skip-sources β€” activates skipping the analysis of methods declared as sources in the taint. (conversely: --no-pulse-taint-skip-sources) 🌈
  • --pulse-taint-sources json β€” okay so this one is a big one, bestie. Together with --pulse-taint-sanitizers, --pulse-taint-sinks, --pulse-taint-policies, and --pulse-taint-data-flow-kinds, you use it to specify taint properties. And the JSON format of sources also applies to sinks and sanitizers, iykyk πŸ’…. It's a list of objects, and each object has one of these combos of fields to identify the relevant procedures:
    • "field_regex" β€” match a field name using an OCaml regex
    • "procedure" β€” match a substring of the procedure name
    • "procedure_regex" β€” as above, but match using an OCaml regex
    • "class_name_regex" β€” match all methods of classes whose names match the OCaml regex
    • "class_names" and "method_names" β€” match exact uses of methods of particular classes
    • "class_names" and "procedure_regex" β€” match exact uses of methods of particular classes matching specified OCaml regex
    • "class_names" and "field_names" β€” match exact uses of fields of particular classes
    • "class_names" and "method_return_type_names" β€” match exact uses of methods with particular return types of particular classes
    • "class_name_regex" and "procedure_regex" β€” match methods based on separate OCaml regexes for both classes and procedure names
    • "class_with_annotation" β€” match all procedures defined in a class annotated with specified annotation
    • "overrides_of_class_with_annotation" β€” match all procedures defined in classes which inherit from a superclass with the specified annotation
    • "method_with_annotation" β€” match all procedures marked by specified annotation
    • "method_with_annotation" and "annotation_values" β€” match all procedures marked by specified annotation with specified values
    • "class_with_annotation", "class_name_regex" and "procedure_regex" β€” match procedures based on specified class annotation and separate OCaml regexes for both classes and procedure names
    • "field_with_annotation" β€” match all fields marked by specified annotation
    • "field_with_annotation" and "annotation_values" β€” match all fields marked by specified annotation with specified values
    • "allocation" β€” (for taint sources only) match allocations of the exact class name supplied
    • "builtin" β€” match a substring of the builtin name (currently only for Hack)
    • "block_passed_to" β€” (for taint sources only) match a substring of the procedure name that the block is passed to
    • "block_passed_to_regex" β€” (for taint sources only) as above, but match using an OCaml regex

Every object can also optionally specify:

  • "kinds" β€” the kinds of taint, used in --pulse-taint-policies to specify flows between sources/sanitizers/sinks ("Simple" by default).
  • "taint_target" β€” where the taint should be applied in the procedure or field.
    • "ReturnValue" β€” (default for taint sources and propagators)
    • "AllArguments" β€” (default for taint sanitizers and sinks)
    • ["ArgumentPositions", [<int list>]] β€” argument positions given by index (zero-indexed)
    • ["AllArgumentsButPositions", [<int list>]] β€” all arguments except given indices (zero-indexed)
    • ["ArgumentsMatchingTypes", [<type list>]] β€” arguments with types containing supplied strings
    • "InstanceReference" β€” this/self references of instance methods
    • ["FieldsOfValue", [<(string * taint_target) list>]] β€” fields given by name in return value, arguments or other fields
    • "GetField" β€” a given field is read
    • "SetField" β€” a given field is set
N.B. for methods, index 0 is this/self. 🫢

For all the regex-based matchers, we can also specify:

  • "exclude_from_regex_in" β€” to specify a list of header files, such that we exclude any classes, field or methods from those files from the regexes.

For field matchers, we can also specify:

  • "sanitized_in" β€” to specify a list of files where using the source shouldn't be flagged.
  • --pulse-widen-threshold int β€” stop exploring new paths after int loop iterations ✨
  • --python-async-function-naming-convention-regex +string β€” consider any function call that matches as returning an unawaited value
  • --python-async-method-naming-convention-regex +string β€” consider any method call that matches as returning an unawaited value
  • --python-decorator-modelled-as-await-async +string β€” any decorator that should be modelled as the await_async decorator.

🧡 RACERD CHECKER OPTIONS 🧡

  • --racerd-always-report-java β€” activates: every Java class analysed is treated as if it were annotated as @ThreadSafe. (Conversely: --no-racerd-always-report-java)
  • --racerd-guardedby β€” activates: check @GuardedBy annotations with RacerD (Conversely: --no-racerd-guardedby)
  • --racerd-ignore-classes +string β€” any method in a class specified here will be ignored by RacerD.
  • --threadsafe-aliases json β€” specify custom annotations that should be considered aliases of @ThreadSafe

🌸 SIOF CHECKER OPTIONS 🌸

  • --siof-check-iostreams β€” activates: do not assume that iostreams (cout, cerr, ...) are always initialized. The default is to assume they are always initialized to avoid false positives. However, if your program compiles against a recent libstdc++ then it is safe to turn this option on. (Conversely: --no-siof-check-iostreams)
  • --siof-safe-methods +string β€” methods that are SIOF-safe; "foo::bar" will match "foo::bar()", "foo<int>::bar()", etc. (can be specified multiple times)

🌍 ENVIRONMENT 🌍

INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

See the ENVIRONMENT section in the manual of infer(1). πŸ’œ


πŸ“ FILES πŸ“

.inferconfig

See the FILES section in the manual of infer(1). πŸŽ€


πŸ‘€ SEE ALSO πŸ‘€

infer-report(1), infer-run(1)


okay that's the whole page bestie, you ate that πŸ’…βœ¨ go forth and analyze, no cap πŸ¦‹

v1.3.0-unknown Β· 2026-10-27 β€” that's the version and the date, keep 'em safe in your notes πŸ‘‘πŸ’–

πŸ“¦ where this page comes from