fold/docs/internal/ir-cross-language-research.md
trvon 18ce5a6050
docs: Swift/C++ ABI, fuzzing, IR, MIR research for multi-language pipeline
- Swift ABI: tagged pointers, garbage-input abort path, ObjC bridging
- C++ fuzz: libFuzzer dlopen coverage limits, AFL++ QEMU mode, vtable seeding
- Cross-language IR: CodeQL/Infer/Joern patterns, Swift SIL gaps in fold IR
- MIR verification: Kani/Prusti/Creusot approaches, BorrowTracker wiring
2026-05-28 10:28:41 -04:00

48 lines
2.8 KiB
Markdown

# Cross-Language IR Research for Multi-Language SAST
> Generated 2026-05-28. Research on unifying fold's IR across C++, Rust, and Swift.
## Existing Multi-Language IR Approaches
**CodeQL**: AST-based with DataFlow and TaintTracking libraries. Language-specific AST nodes with a shared property graph layer. C++, Java, Python, JavaScript, Go, Ruby, Swift all use the same query language but different AST schemas.
**Semgrep**: Generic AST with language-specific patterns. The "generic" mode uses tree-sitter grammars — any language with a tree-sitter grammar is supported. Not a true IR — purely syntactic matching.
**Infer (Facebook)**: SIL (Smallfoot Intermediate Language) — a simple imperative language with memory operations, function calls, and assume/assert. Clang frontend lowers C++ to SIL, which the analysis engines operate on. Single IR for all languages.
**Joern (Code Property Graphs)**: AST + CFG + PDG combined into a graph database. Queries traverse edges across representation layers. Language-specific frontends produce a unified CPG.
## fold's Current IR
`expr_json.hpp` defines `RustExprNode` with kinds:
- IntegerLiteral, BoolLiteral, NullPtr, DeclRef
- BinaryOp, Deref, ArraySubscript, UnaryOp, AddrOf
- Cast, Call, Member, HeapNew, HeapDelete, StringLiteral, Conditional
**Gap analysis for Swift SIL parity:**
| Swift SIL Concept | fold IR Equivalent | Status |
|-------------------|-------------------|--------|
| `alloc_stack` | HeapNew (close) | Has struct — unused |
| `load` / `store` | Deref + assignment | Partial |
| `apply` (function call) | Call | Has struct, unused in Swift path |
| `switch_enum` | Switch + discriminant | **Missing** |
| `unchecked_ref_cast` | Cast (has kind) | **Not wired for Swift** |
| `existential` type erasure | **Missing entirely** | Needs new node kind |
| `protocol witness` dispatch | Indirect Call | **Not implemented** |
| `optional` binding (`switch_enum_addr`) | Conditional + member | **Missing** |
## What's Needed for Swift IR
1. **Add `SwitchEnum` kind** to `json_keys` and `RustExprNode`
2. **Wire `encodeRustIr` → `encodeSwiftIr`**: rename or generalize the encoder to accept language-agnostic node trees
3. **Swift-specific observer hooks**: `onOptionalUnwrap`, `onProtocolDispatch`
4. **Map SWAN-parsed SIL to IR trees**: the SWAN parser produces structured SIL — need to tree-ify it for the encoder
## Recommended Approach
**Phase 1**: Generalize `RustExprNode` → `IrExprNode` with a `language` discriminator. Add missing kinds (SwitchEnum, OptionalBind, ProtocolWitness). Wire Swift SWAN output into the same pipeline.
**Phase 2**: Add Swift-specific SafetyObserver hooks. The observer interface already has language-agnostic overloads from the architecture expansion.
**Phase 3**: Unify the Z3 encoder for all languages. The `encodeRustIr` function becomes `encodeIr` that dispatches by `language` field.