A simplified model of Fil-C

Fil-C is a memory-safe implementation of C/C++ that uses a simplified model of source code rewriting and metadata tracking to ensure safety. By introducing an AllocationRecord and a garbage collector, it transforms unsafe pointer operations into checked, secure executions.
I've seen lots of chatter about Fil-C recently, which pitches itself as a memory safe implementation of C/C++. You can read the gritty details of how this is achieved, but for people coming across it for the first time, I think there is value in showing a simplified version, as once you've understood the simplified version it becomes a smaller mental step to then understand the production-quality version.
The real Fil-C has a compiler pass which rewrites LLVM IR, whereas the simplified model is an automated rewrite of C/C++ source code: unsafe code is transformed into safe code. The first rewrite is that within every function, every local variable of pointer type gains an accompanying local variable of AllocationRecord* type.
Where AllocationRecord is something like:
struct AllocationRecord {
char* visible_bytes;
char* invisible_bytes;
size_t length;
};
Trivial operations on local variables of pointer type are rewritten to also move around the AllocationRecord*. When pointers are passed-to or returned-from functions, the code is rewritten to include the AllocationRecord* as well as the original pointer. Calls to particular standard library functions are additionally rewritten to call Fil-C versions of those functions.
The (simplified) implementation of filc_malloc actually performs three distinct allocations rather than just the requested one: the record itself, the visible bytes, and the invisible bytes (shadow memory for pointers).
When a pointer variable is dereferenced, the accompanying AllocationRecord* is used to perform bounds checks. Things become more interesting when the value being stored or loaded is itself a pointer. If there is a pointer at visible_bytes + i, then its accompanying AllocationRecord* is at invisible_bytes + i.
Fil-C also introduces a Garbage Collector (GC). The collector traces through AllocationRecord objects and frees unreachable ones. This means forgetting to call free is no longer a memory leak. Furthermore, if a local variable's address escapes its scope, Fil-C promotes it to heap-allocation.
Production-quality Fil-C handles additional complexities like threads (concurrency), function pointers (type confusion protection), and heavy performance optimizations to mitigate the overhead of memory safety checks.
Source: Hacker News










