Static Analysis

Static analysis is the technique of analyzing code without executing it — examining source code, bytecode, or intermediate representations to detect bugs, security vulnerabilities, code quality issues, and verify properties, all without running the program.

What Is Static Analysis?

Static Analysis — Finding Bugs Without Running Code examine source/bytecode at compile time to detect defects, vulnerabilities, and style violations Static Analysis Pipeline Source Code C/C++/Java/ Python/Go or bytecode Parse → AST control flow graph data flow graph call graph Analysis Engine abstract interpretation pattern matching taint tracking Findings bugs, vulns + line numbers + fix suggestions CI Gate pass/fail block merge if new bugs What Static Analysis Finds Memory bugs: null deref, buffer overflow, use-after-free, leaks Concurrency: data races, deadlocks, atomicity violations Security: SQL injection, XSS, path traversal (taint analysis) Logic: dead code, unreachable, redundant conditions Type: type confusion, unchecked casts, missing generics false positive rate: 15–40% (trade-off with coverage) soundness: over-approximate → may report impossible bugs (safe side) Tools & Ecosystem C/C++: Coverity, CodeQL, Infer, clang-tidy, Polyspace Java: SpotBugs, ErrorProne, PMD, SonarQube Python: mypy, pytype, Bandit, Ruff, Pylint Multi-lang: Semgrep, CodeQL (GitHub), Snyk Code AI-powered (2024+): LLM + static analysis hybrid (Amazon CodeGuru, Qodo, GitHub Copilot code scanning) static analysis catches bugs at commit time — 100× cheaper than finding them in production Static analysis is the first line of defense — it finds entire classes of bugs before a single test runs.
  • Static: Analysis performed on code at rest — no execution required.
  • Automated: Tools automatically scan code to find issues.
  • Scalable: Can analyze large codebases quickly.
  • Early Detection: Finds bugs during development, before code runs.

Why Static Analysis?

  • Find Bugs Early: Detect issues before code reaches production — cheaper to fix.
  • No Test Cases Needed: Unlike testing, doesn't require writing tests or generating inputs.
  • Comprehensive: Can analyze all code paths, including rare or hard-to-test scenarios.
  • Security: Find vulnerabilities that could be exploited — SQL injection, buffer overflows, etc.
  • Code Quality: Enforce coding standards, detect code smells, improve maintainability.

Types of Static Analysis

  • Syntactic Analysis: Check code structure and syntax.
  • Parsing, syntax checking, style enforcement.
  • Tools: linters (ESLint, Pylint, RuboCop).
  • Type Checking: Verify type correctness.
  • Ensure variables are used consistently with their types.
  • Tools: TypeScript, MyPy, Flow.
  • Data Flow Analysis: Track how data flows through the program.
  • Detect uninitialized variables, unused values, null pointer dereferences.
  • Tools: FindBugs, SpotBugs, Infer.
  • Control Flow Analysis: Analyze program control flow.
  • Detect unreachable code, infinite loops, missing return statements.
  • Taint Analysis: Track untrusted data flow.
  • Detect when user input reaches sensitive operations without sanitization.
  • Find SQL injection, XSS, command injection vulnerabilities.
  • Abstract Interpretation: Soundly approximate program behavior.
  • Prove absence of certain bug classes.
  • Tools: Astrée, Polyspace.

Common Bug Types Detected

  • Null Pointer Dereferences: Accessing null/None objects.
  • Buffer Overflows: Writing beyond array bounds.
  • Resource Leaks: Not closing files, connections, or freeing memory.
  • Concurrency Bugs: Race conditions, deadlocks, data races.
  • Security Vulnerabilities: Injection attacks, authentication bypasses, crypto misuse.
  • Logic Errors: Unreachable code, infinite loops, incorrect conditions.
  • Code Quality Issues: Dead code, duplicated code, overly complex functions.

Example: Static Analysis Detecting Bugs

# Bug 1: Null pointer dereference
def process_user(user):
    return user.name.upper()  # What if user is None?

# Static analysis warning: "user may be None"

# Bug 2: Resource leak
def read_file(filename):
    f = open(filename)
    data = f.read()
    return data  # File never closed!

# Static analysis warning: "Resource leak: file not closed"

# Bug 3: SQL injection
def get_user(username):
    query = f"SELECT * FROM users WHERE name = '{username}'"
    return execute_query(query)

# Static analysis warning: "SQL injection vulnerability: unsanitized user input"

Static Analysis Techniques

  • Pattern Matching: Look for known bug patterns.
  • Example: `if (x = 5)` instead of `if (x == 5)` — assignment in condition.
  • Type Inference: Infer types and check consistency.
  • Example: Detect when a function expecting int receives string.
  • Symbolic Execution: Explore paths symbolically without concrete values.
  • Example: Determine if null check is missing on a path.
  • Abstract Interpretation: Compute abstract values representing sets of concrete values.
  • Example: Track that a variable is "positive" or "possibly null."
  • Model Checking: Verify properties against a model of the program.
  • Example: Prove that a lock is always released.

Static Analysis Tools

  • General Purpose:
  • SonarQube: Multi-language code quality and security analysis.
  • Coverity: Commercial static analyzer for C/C++, Java, C#.
  • Fortify: Security-focused static analysis.
  • Language-Specific:
  • Pylint / Flake8 (Python): Style and bug detection.
  • ESLint (JavaScript): Linting and bug detection.
  • RuboCop (Ruby): Style and bug detection.
  • FindBugs / SpotBugs (Java): Bug detection.
  • Clang Static Analyzer (C/C++): Bug detection.
  • Security-Focused:
  • Bandit (Python): Security issue detection.
  • Brakeman (Ruby on Rails): Security vulnerability scanner.
  • Semgrep: Pattern-based security and bug detection.

Soundness vs. Completeness

  • Sound Analysis: Never misses bugs (no false negatives) — but may report false positives.
  • Conservative: Reports potential bugs even if uncertain.
  • Example: Abstract interpretation tools.
  • Complete Analysis: Never reports false positives — but may miss bugs (false negatives).
  • Optimistic: Only reports definite bugs.
  • Most practical tools are incomplete.
  • Trade-Off: Sound tools have many false positives (noise). Complete tools miss bugs. Most tools balance between the two.

Challenges

  • False Positives: Reporting bugs that don't exist — developers ignore warnings if too many false positives.
  • False Negatives: Missing real bugs — no tool finds all bugs.
  • Scalability: Analyzing large codebases can be slow.
  • Precision: Balancing precision (few false positives) with recall (few false negatives).
  • Undecidability: Some properties are undecidable — perfect analysis is impossible.

LLMs and Static Analysis

  • Bug Detection: LLMs can identify bug patterns in code.
  • False Positive Reduction: LLMs can help filter false positives from static analyzers.
  • Explanation: LLMs can explain why code is flagged and how to fix it.
  • Custom Rules: LLMs can help developers write custom analysis rules.

Applications

  • Continuous Integration: Run static analysis on every commit — catch bugs early.
  • Code Review: Automated pre-review to catch obvious issues.
  • Security Audits: Find vulnerabilities before deployment.
  • Compliance: Ensure code meets standards (MISRA C, CERT C, etc.).
  • Refactoring: Identify code smells and improvement opportunities.

Benefits

  • Early Bug Detection: Find bugs before testing or deployment.
  • No Execution Needed: Analyze code that's hard to test or run.
  • Comprehensive Coverage: Analyze all code paths, not just tested ones.
  • Automated: Requires minimal human effort once set up.

Limitations

  • Cannot Find All Bugs: Some bugs require runtime information or complex reasoning.
  • False Positives: Can report non-issues, leading to alert fatigue.
  • Configuration: Requires tuning to balance precision and recall.

Static analysis is a fundamental software engineering practice — it provides automated, scalable bug detection that complements testing and code review, improving code quality and security throughout the development lifecycle.

Take static analysis further

Ask the copilot about this term, or have our engineers assess it against your process.