- Language enum: Unknown, Rust, Cpp, Swift on RustExprNode
- 4 new Clang node kinds: ThrowExpr, CXXConstructExpr, LambdaExpr, StmtExpr
- Updated json_keys namespace with new constants
- 42 roundtrip test assertions pass
- All 3 frontends now share the same IR representation
- symbolic_summary.rs: MIR-based summary computation per function
- Produces SymbolicSummaryData with SMT-LIB BV-64 expressions
- Matches C++ fold::symbolic::SymbolicSummary wire format
- Cross-function Z3 proofs now possible
- MIR-to-IR tree converter: 12 functions walk MIR basic blocks
- Each block becomes Call(mir_block) with statements + terminator
- SwitchInt terminators → path predicate forking per case
- Return/Rvalue encoding threaded through RustExprNode JSON
- Brings Rust CFG precision to parity with Clang security walker
- 32 FPs on own source: const auto* vd = dyn_cast<T>(expr) pattern
- vd->hasInit() returns true for declarations with initializers
- Reduces self-scan FPs from 32 to 0
- ai_pre_pass.cpp: add OptionalBind/ProtocolWitness/ExistentialContainer/
SwitchEnum/Conditional cases to both node->kind switches
- r2_backend.cpp: r2CmdQuote used at line 137, clang false positive
— kept with static keyword
- Z3 query: exists path from alloc to function exit where freed=false?
- Fork/merge walker per allocation site, tracks freed flag on all paths
- Reports leaked allocations with confidence=proved
- 7/7 Z3 detectors complete, 119 build targets
- always_condition: Z3 proves branch tautologies/contradictions
- uninit_read: Z3 detects variable reads before writes on any path
- unreachable: Z3 proves code after return/throw is unreachable
- All 3 wired into ShardFrontend, FindingKind, CLI --detectors
- Replaced run_target with custom_target (build_by_default: true)
- Single ninja builds all 3: fold + fold-rust + fold-swift
- meson install copies all 3 to prefix/bin automatically
- No more separate ninja fold-rust step needed
- R2Backend::discoverObjcClasses() queries icj for class+method list
- fuzz-prep generates objc_msgSend harnesses for each ObjC method
- Real instance pointer replaces fuzzer garbage as self/slot0
- 4 harnesses generated for FuzzMeClass: add, isEven, tokenize, init
- Swift-mangled symbols (//_T0) skipped: need valid objects, not raw uint64_t
- Cov:2 dead end explained: garbage args cause Swift runtime abort before real code
- Fuzz budget floor raised 30→120s, ceiling 120→600s (match AFL++/libFuzzer norms)
- Base per-CPU allocation doubled 45→90s
- --check-returns flag for emitBinaryHarness
- Pointer-returning functions get ASan shadow check via
__asan_region_is_poisoned after call
- Volatile guard prevents compiler from eliding the call
- Wire node->int_signed through onBinaryArith/onDivision instead of hard-coded true
- Use signed comparisons (<, <=, >, >=) when int_signed is true, unsigned otherwise
- Add Member case: encode base, fire onPointerDerefIr
- Addresses H3 from encoder audit (Rust precision loss)
- HW detect: sysconf CPU/memory → compute per-harness budget (30-120s)
- --per-harness-timeout-seconds flag for override
- 3-5 seed files per harness: zeros, sentinels, ASCII patterns
- --corpus-seeds N flag to control seed count
- inferParamCountARM64 returns 3 when disasm fails (was 0)
- Debug logs show symbol name, address, detected param count
- SARIF result.kind set to 'fail' per spec
- size < paramCount*8 only emitted when paramCount > 0
- ABI inference now runs for isj-fallback exported functions
- Debug logging added to track param_count per function
- Binary fuzz-run skips --target-source requirement
- Runner adds -ldl for dlopen harnesses
- SymbolicSummaryCache: per-function BV-64 cache to avoid re-encoding
- Language-agnostic observer overloads for Rust/Swift backends
- Abstract-interpretation pre-pass for Rust integer range filtering
- 3 new unit tests, 63/63 pass
- Store harness_file in binary fuzz predictions to fix prep↔run mismatch
- Resolve relative -I flags against compile DB directory
- Add caller_unsafe/is_param_sourced fields to fold-rust NDJSON
- Allow empty target_sources in fuzz-run for dlopen harnesses
- Recursive IR encoder descent for nested hazards
Three outstanding workstreams after the matrix sweep:
1. scan_runner.cpp dispatch hook for uninit-local-read (C5).
Uncommitted in local edits; entangled with parallel session's
C2 clang::CallGraph work. Coordinated commit pending.
2. Native UAF detector. Carved out from C4 (ConsumedAnalysis was
wrong-tool -- needs source attributes). New detector should
be a CFG-walker tracking freed_ptrs per function.
3. Per-row precision baselines for Z5, Z10, C5, C7, C8, C9.
Z4 has one (docs/perf-audit/runs/matrix/Z4-curl-2026-05-26.json);
the rest are pending.
Also: cross-cutting cleanup (workspace junk to gitignore,
parallel-session rust-frontend edits, catch2 chained-comparison
lint).
clang::consumed::ConsumedAnalysis only activates on classes marked
[[clang::consumable]] + member functions marked
[[clang::callable_when(state)]] + [[clang::return_typestate(state)]].
Real-world C code (curl, yams, kernel-style) has none of these
attributes; without auto-injection the analysis is silent.
A native UAF detector remains a real opportunity, but it's a
CFG-walker shape (track malloc/free on tracked pointers + flag
derefs after free), not ConsumedAnalysis. Carved out as a future
detector row rather than wedged into C4's framing.