Map

Fil-C

Toolbox toolboxccppmemory-safetycompilerllvmC/C++Apache-2.0 โ†ณ show in map Markdown
title
Fil-C
type
toolbox
summary
Memory-safe C/C++ compiler giving every pointer a bounds-checked capability and a GC, no rewrites
tags
c, cpp, memory-safety, compiler, llvm
language
C/C++
license
Apache-2.0
created
2026-04-18
updated
2026-04-18

A memory-safe implementation of C/C++. Fil-C adds an LLVM IR pass that rewrites pointer operations to carry a shadow "capability" (an AllocationRecord*) alongside every pointer, performs bounds checks on every dereference, and runs a garbage collector to manage the lifetime of the capability records. The result is C/C++ that survives bounds violations, use-after-free, and type confusion without rewriting source code.

How it works

Three ideas, in layers:

  • Shadow capability per pointer. Every pointer is paired with an AllocationRecord* tracking its allocation's bounds (visible_bytes, length). Dereferences check bounds against this record. See simplified-model-of-fil-c for the full walkthrough.
  • Parallel shadow heap for stored pointers. Each allocation has a visible_bytes array (user data) and an invisible_bytes array (same size, element type AllocationRecord*). When user code loads or stores a pointer in memory, Fil-C also loads/stores the capability from the parallel index. This is how capabilities survive being written through memory.
  • Parallel concurrent incremental GC (FUGC). AllocationRecord objects are never freed explicitly; the GC handles them. This means forgetting free is not a leak, and use-after-free is safe (freed records get canonicalised to a single length-0 sentinel).

Additional production features: escape-analyzed locals get heap-promoted automatically, function pointers carry a distinct capability flag with a uniform ABI, and atomic pointer ops use custom lowering to preserve atomicity across the paired load.

See pointer-provenance โ€” Fil-C is a concrete system that makes provenance semantics observable, because equal pointers can carry different AllocationRecord* values.

Use cases

  • Legacy C/C++ you want memory-safe without a full rewrite, typically as a bridge to eventual migration.
  • A stronger alternative to ASan for finding memory bugs.
  • Safe compile-time evaluation in languages like Zig where compile-time and runtime share a language.
  • A teaching example for memory-model concepts like provenance.

Limitations

  • Performance cost is large. Every dereference is a bounds check; every pointer load/store is doubled. Optimisations claw some of this back but not all.
  • Forces a GC into C/C++. For systems where GC pauses are unacceptable, Fil-C isn't the right fit.
  • ABI changes. Functions take paired (pointer, AllocationRecord*) arguments; interop with unmodified C code needs wrappers.
  • memmove semantics quirk. Aligned multi-byte memmove moves shadow memory along with user bytes; misaligned or byte-wise copies don't. This can silently lose capabilities if code relies on unaligned memory layouts.

Homepage: fil-c.org. Technical deep dive: Invisicaps. Collector: FUGC.

Sub-pages