v0.5.0Roslyn 5.3.0 upgrade — convert C# 14 code to Calor, exhaustive match enforcement on sum types.See what's new

Static Analysis (--analyze)

Find bugs in Calor code using dataflow analysis, Z3 verification, and taint tracking.

Bash
calor --input <file.calr> --analyze [--all-findings]

Overview

The --analyze flag enables advanced static analysis on Calor source files. It runs after compilation and uses the bound syntax tree to detect bugs that C# alone cannot catch:

  • Division by zero — proven via Z3 SMT solver or constant analysis
  • Null dereference — unsafe .unwrap() on Option/Result types without prior checks
  • Integer overflow — Z3-verified signed overflow in arithmetic operations
  • Index out of bounds — array access with provably negative indices
  • Off-by-one errors — loop bounds vs. array length mismatches
  • SQL injection — tainted user input flowing to SQL queries
  • Command injection — tainted data reaching command execution
  • Path traversal — tainted data used as file paths
  • Cross-site scripting — tainted data in HTML output

By default, only verified findings are reported — issues that are proven by Z3 or constant analysis. Use --all-findings to see lower-confidence results.


Quick Start

Bash
# Analyze a Calor file for bugs
calor -i MyModule.calr --analyze --permissive-effects

# Analyze with all findings (including inconclusive)
calor -i MyModule.calr --analyze --all-findings --permissive-effects

# Combine with contract verification
calor -i MyModule.calr --analyze --verify --permissive-effects

Options

OptionDescription
--analyzeEnable static analysis (dataflow, bug patterns, taint tracking)
--all-findingsReport all findings including inconclusive and low-confidence results
--permissive-effectsRecommended for converted code: suppresses unknown-effect warnings
--verification-timeoutZ3 solver timeout per check in milliseconds (default: 5000)
--verboseShow analysis summary (functions analyzed, patterns found)

What Gets Detected

Bug Patterns (Calor0920-0927)

CodePatternSeverityMethod
Calor0920Division by zeroError (proven) / Warning (Z3)Constant analysis + Z3 SMT
Calor0921Index out of boundsError / WarningNegative literal + Z3
Calor0922Null dereferenceWarningUnwrap pattern analysis
Calor0923Integer overflowWarningZ3 bitvector arithmetic
Calor0925Unsafe unwrapWarningOption/Result flow tracking
Calor0926Missing preconditionWarningDivisor parameter analysis
Calor0927Off-by-oneWarningLoop bounds heuristic

Security (Calor0980-0984)

CodePatternSeverityMethod
Calor0981SQL injectionWarningTaint tracking (source-to-sink)
Calor0982Command injectionWarningTaint tracking
Calor0983Path traversalWarningTaint tracking
Calor0984Cross-site scriptingWarningTaint tracking

Dataflow (Calor0900-0902)

CodePatternSeverityMethod
Calor0900Uninitialized variableError / WarningCFG-based reaching definitions
Calor0901Dead codeWarningControl flow analysis
Calor0902Dead storeWarningLive variable analysis

Default vs. --all-findings

The --analyze flag uses verification-gated reporting by default. This means:

Finding typeDefault (--analyze)--all-findings
Division by literal zeroReportedReported
Z3-proven division by zeroReportedReported
Inconclusive division checkSuppressedReported as Info
Heuristic-only findingsSuppressedReported as Warning
Missing precondition suggestionsSuppressedReported as Warning
Multi-hop taint flows (2+ hops)ReportedReported
Single-hop taint flowsSuppressedReported

This approach follows the principle used by tools like Infer, Error Prone, and the Rust compiler: report only what you can prove.


Real-World Findings

The analysis has found verified issues across 51 open-source C# projects converted to Calor:

ProjectFindingType
ILSpyUnsafe unwrap in NullPropagationTransformNull dereference
MapsterNullable type unwrap without checkNull dereference
AvaloniaNullable unwrap in Android platform codeNull dereference
FluentFTPRemote file paths used without sanitizationPath traversal
ASP.NET CoreTainted data in file handlingPath traversal
Newtonsoft.JsonFloatingPointRemainder(dividend, 0)Division by zero

Class Member Analysis

The analysis covers all executable class members:

  • Methods (§MT) — including overloaded methods with arity-aware resolution
  • Constructors (§CTOR) — including initializer argument analysis
  • Property accessors (§PROP get/set/init) — with implicit value parameter
  • Operator overloads (§OP) — arithmetic operators checked for overflow
  • Indexers (§IXER) — getter/setter bodies
  • Event accessors (§EVT add/remove) — with implicit value parameter

Class fields are in scope for all member bodies, preventing false uninitialized-variable reports.


Integration with CI/CD

Use calor diagnose --format sarif for SARIF output compatible with GitHub Code Scanning and other tools:

Bash
# Generate SARIF report
calor diagnose MyModule.calr --format sarif --output results.sarif

# Combine with static analysis
calor -i MyModule.calr --analyze --permissive-effects 2> analysis-output.txt

Performance

Analysis adds minimal overhead to compilation:

File sizeMethodsAnalysis time
Small (50 tokens)2-5< 100ms
Medium (1K tokens)10-30200-500ms
Large (5K tokens)50-100500ms-2s

Z3 verification adds 1-5 seconds per file depending on the number of contracts and the --verification-timeout setting.