Skip to content

Latest commit

 

History

History
122 lines (90 loc) · 7 KB

File metadata and controls

122 lines (90 loc) · 7 KB

AGENTS.md

This file provides guidance to Open Code / Codex / Claude Code (claude.ai/code) when working with code in this repository.

What is Infer?

Infer is a multi-language static analysis tool developed by Meta. It detects bugs in Java, C, C++, Objective-C, Erlang, Hack, Python, Rust, Swift, and C# code. The primary implementation language is OCaml.

Build Commands

All build commands run from the repository root. You must have run ./build-infer.sh and make devsetup initially.

Command Purpose
make -j Full native build (default dev mode, warnings are fatal)
make -j BUILD_MODE=dev-noerror Build ignoring warnings
make -j -C infer/src check Type-check only (fastest iteration cycle, requires prior full build)
make -j -C infer/src byte Bytecode build (for testing changes quickly)
make opt Optimized build with flambda
make fmt Format changed OCaml files with ocamlformat
make fmt_all Format all OCaml files

Testing

Command Purpose
make -j 4 test Run all tests (adjust parallelism to your cores)
make -j test_build Verify build has no warnings
make test-replace Update expected test outputs after intentional changes
make direct_{lang}_{analyzer}_test Run a single test suite (rebuilds infer first)
make -C infer/tests/codetoanalyze/{lang}/{analyzer}/ test Run a single test suite (assumes infer is up-to-date)
make ocaml_unit_test Run OCaml unit tests only
make swift_tests Run Swift tests (separate from main test target)

Direct test names follow the pattern {lang}_{analyzer}, e.g., direct_java_pulse_test, direct_cpp_pulse_test, direct_c_frontend_test. These are defined in the DIRECT_TESTS variable in the root Makefile.

Test structure

Tests live in infer/tests/codetoanalyze/{language}/{analyzer}/. Each test directory has:

  • Source files to analyze
  • issues.exp with expected output (one issue per line)
  • Makefile that runs infer and diffs output against issues.exp

Test procedure naming conventions:

  • *Bad — should report an error
  • *Ok — should not report an error
  • FP_* — false positive (known limitation, include explanatory comment)
  • FN_* — false negative (known limitation, include explanatory comment)

Debugging analysis

infer --debug -- clang -c examples/hello.c
firefox infer-out/captured/hello.c.*.html

Architecture

Frontends (language → SIL translation)

Each supported language has a frontend that translates source code into SIL (Separation Logic Intermediate Language), defined in infer/src/IR/:

Directory Language Mechanism
clang/ C/C++/Objective-C Custom clang plugin (facebook-clang-plugins/)
java/ Java javalib/Sawja bytecode parsing
erlang/ Erlang Erlang compiler integration
python/ Python PyML-based frontend
rust/ Rust Charon IR translation
llvm/ LLVM bitcode LLVM OCaml bindings (used by Swift)
textual/ Textual SIL Text-based SIL representation (Hack, Python, LLVM)

Intermediate Representation (infer/src/IR/)

Core types: Sil.ml (instructions), Procdesc.ml (procedure descriptors), Typ.ml (types), Procname.ml (procedure names), Tenv.ml (type environments).

Analysis engines

  • Pulse (pulse/, ~150+ files) — The main abstract domain. Handles memory safety, taint tracking, null safety, resource leaks via abductive reasoning.
  • Abstract interpretation framework (absint/) — AbstractDomain.ml, AbstractInterpreter.ml define the fixpoint computation infrastructure.
  • Buffer overrun (bufferoverrun/) — Array bounds analysis.
  • Concurrency (concurrency/) — Race condition detection (RacerD).
  • Cost (cost/) — Computational cost analysis.
  • TOPL (topl/) — Temporal property checking.
  • Checkers (checkers/) — Miscellaneous checkers (liveness, purity, annotations, etc.).

Backend (infer/src/backend/)

Analysis scheduling (AnalysisDependencyGraph.ml), call graph construction (CallGraph.ml), checker registration (callbacks.ml), reporting.

Configuration (infer/src/base/Config.ml)

Very large file (~189KB) defining all command-line options. Uses CommandLineOption module (aliased CLOpt).

OCaml Coding Conventions

  • 100-character line limit. Format with ocamlformat.
  • IStd is auto-opened in every file. Always write open! IStd explicitly at the top.
  • Polymorphic equality is disabled. Use type-specific equality (e.g., Int.equal, String.equal). Use PolyVariantEqual only for modules heavy on argument-free polymorphic variants.
  • Standard module aliases (use consistently, do not alias these names to other modules):
    module CLOpt = CommandLineOption
    module F = Format
    module L = Logging
    module MF = MarkupFormatter
  • Printf debugging: Use Logging.debug_dev (triggers a warning to prevent accidental commits).
  • Use [@@deriving compare, equal] for comparison/equality derivations.
  • Use named arguments when purpose isn't obvious, especially for bool/int params and function-typed params (conventionally named f).
  • Avoid globally opening modules other than IStd and PolyVariantEqual.
  • OCaml debugger: Module M is really InferModules__M (or InferBase__M, etc.) when setting breakpoints in ocamldebug.

Key Files

  • infer/src/base/Config.ml — All CLI options
  • infer/src/IR/Sil.ml — SIL instruction definitions
  • infer/src/absint/AbstractInterpreter.ml — Fixpoint computation
  • infer/src/pulse/PulseAbductiveDomain.ml — Pulse's core abstract state
  • infer/src/dune — Main dune build config (generated from dune.common + dune.in)
  • Makefile — Test targets and build orchestration