Module 6 — Program Analysis Bootcamp
From individual analyses to integrated tools
Click each analysis pass to see what it finds in the same code.
Click a pass button to see what it detects.
All passes must speak the same language — a unified finding record.
Sort, filter, and deduplicate — because all passes produce the same type.
Each analysis is packaged as a record with a uniform interface.
program → finding listA purely AST-level analysis — no abstract domains needed.
| Pattern | Severity |
Unreachable after Return | Medium |
| Unused variables | Low |
| Unused parameters | Info |
Return + trailing stmtsExisting analyses become passes by wrapping them and converting results to finding records.
finding records. This is the power of good abstractions.
For each scenario, choose the correct severity and category.
A variable user_input flows directly into exec() without any sanitization.
Function compute(x) is defined but never called anywhere in the program.
Division by variable y where sign analysis shows y could be zero.
Variable count is assigned on line 3 but overwritten on line 4 without being read.
Run multiple analysis passes over the same AST and merge their findings into a unified report.
Watch as dead code, safety, and security passes analyze the same program — findings accumulate in a unified table.
| Line | Severity | Category | Message |
|---|
A config record controls which passes run, what severity to filter, and output format. Build configs with the |> pipeline operator.
Filters reduce noise by removing low-severity findings, duplicates, and excluded categories. Toggle filters to see the effect live.
The full pipeline: Parse → Analyze → Filter → Deduplicate → Sort → Report. Each stage is a pure function — easy to test and compose.
The same findings can be rendered as human-readable text or machine-readable JSON. Toggle to compare both formats.
A team needs a CI/CD security gate. Build the config that meets their requirements.
Production tools implement exactly the pipeline we built — with richer rules, IDE integration, and CI/CD hooks. Click each to explore.
Watch the complete pipeline process a real program — from source code to final report.
finding record with severity + category + location works for all analysis types. Standardization enables composition.
analysis_pass — a record with name and run. Wrap any M3–M5 analysis into this interface.
|>. Easy to test, extend, reorder.
You've built a complete program analysis toolkit from the ground up.
Each pipeline has a bug. Identify what's wrong and pick the fix.
Team says: "We're missing medium-severity SQL injection findings!"
Team says: "Same finding appears twice in the report!"
Team says: "Filter doesn't work — all findings still show up!"
Team says: "Report is always empty — no findings at all!"
Which field is NOT part of our unified finding type?
What is the correct pipeline stage order?
Why wrap M4/M5 analyses as analysis_pass records?
Given this config and program, predict what the final report contains.
How many findings in the final report?
Which findings survive? (check all that apply)
For each real-world scenario, choose the best design approach.
Your team writes a new "complexity analysis" that measures function complexity. How should you integrate it?
CI takes 10 minutes because dead code analysis is slow on large codebases. What's the best fix?
Your tool needs to work with both GitHub code scanning AND a custom dashboard. What output strategy?
Developers complain about too many false positives from the safety pass. Best approach?