This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Fil-C is a memory-safe implementation of C and C++ created by Filip Pizlo at Epic Games. It provides full C/C++ compatibility while preventing all memory safety errors through a combination of concurrent garbage collection and invisible capabilities (InvisiCap system).
Key characteristics:
- Memory Safety: All pointers carry capabilities tracking bounds and type information
- GIMSO Principle: "Garbage In, Memory Safety Out" - no unsafe escape hatches
- Garbage Collection: Uses FUGC (Fil's Unbelievable Garbage Collector) - concurrent, non-moving GC
- Platform: Currently Linux/X86_64 only
- Performance: 1.5x-5x slower than standard C (actively being optimized)
# For source builds (primary development workflow)
./setup_gits.sh # Clone/setup all required repositories
# Build options (choose one):
./build_all.sh # Basic build with musl
./build_all_glibc.sh # Use glibc instead of musl
# For binary releases
./setup.shbuild_base.sh- LLVM/Clang compilerbuild_runtime.sh- Fil-C runtime (libpas)build_yolomusl.sh/build_usermusl.sh- musl libc implementations (both essential)build_cxx.sh- C++ standard library (essential)
build_yolo_glibc.sh/build_user_glibc.sh- glibc implementations
build_all_fast.sh- Essential components onlybuild_all_slow.sh- All ported applications
filc/run-tests # Run all tests
filc/run-tests --filter regex # Run tests matching pattern
filc/run-tests --test testname # Run specific test
filc/run-tests --verbose # Verbose output
filc/run-tests --no-run # Compile only, don't run- Tests live in
filc/tests/*/directories - Each test has a
manifestYAML file defining expectations - Test runner generates build scripts and runs multiple configurations
- Configurations include: default, scribble (verification), STW (stop-the-world), release
Tests are compiled to filc/test-output/testname/ with scripts:
compile.sh- Build the testjustRun.sh- Run with debug runtimesubRun*.sh- Run with different GC configurations
# Basic compilation
build/bin/clang -o program program.c -g -O
# C++ compilation
build/bin/clang++ -o program program.cpp -g -O -std=c++20
# Must use -g for meaningful error messages
# Must use -O with -g to avoid compiler crashesCompiler Implementation:
llvm/lib/Transforms/Instrumentation/FilPizlonator.cpp- Main LLVM pass implementing Fil-C transformations
Runtime System:
libpas/src/libpas/filc_runtime.{h,c}andlibpas/src/libpas/filc_runtime_inlines.h- Core runtime implementationlibpas/src/libpas/fugc.{h,c}- Garbage collectorlibpas/src/libpas/filc_start_program.c- Program startup trampoline
Fil-C Headers and Runtime:
filc/include/stdfil.h- Main Fil-C headerfilc/src/- Runtime components written in Fil-Cfilc/main/- Program entry point
Libc Implementations:
- musl:
projects/yolomusl/(yolo libc),projects/usermusl/(user libc) - glibc:
projects/yolo-glibc-2.40/(yolo libc),projects/user-glibc-2.40/(user libc)
Ported Applications:
projects/*directories contain memory-safe versions of various software packagespizfix/- Staging environment for compiled Fil-C programs
Fil-C uses a "sandwich" architecture:
- Yolo libc (bottom) - Minimally modified libc for runtime use
- Fil-C runtime (middle) - Memory safety layer
- User libc (top) - Heavily modified libc that applications use
Both yolo and user libc implementations are essential - you cannot have a working Fil-C system without both.
- Each pointer has an associated invisible capability
- Capabilities stored in auxiliary allocations, not visible to C address space
- Pointers in registers use two registers (pointer + capability)
- Enables full C compatibility while maintaining memory safety
- Out-of-bounds access detection (heap and stack)
- Use-after-free prevention
- Type confusion prevention
- Pointer race detection
- System call argument validation
- Fil-C code cannot link with regular C code
- Must port entire dependency chains to Fil-C
- This is fundamental due to incompatible pointer representations
- Always compile with
-gfor meaningful error messages - Use
FUGC_STW=1to force stop-the-world GC for debugging GC issues - Use
FUGC_SCRIBBLE=1 FUGC_VERIFY=1for memory corruption debugging - Use
FILC_DUMP_SETUP=1to verify environment variable settings (useful when using other debugging flags)
- Use
FUGC_MIN_THRESHOLD=0to increase GC churn for stress testing (not for performance tuning) - Default
FUGC_MIN_THRESHOLDvalue is generally optimal for performance
- Current bottlenecks: calling convention overhead, capability access patterns
- Use
-O2or-O3for best performance
Overview.md- Detailed project description and layoutREADME.md- Getting started guideManifesto.md- Technical deep-dive into Fil-C designinvisicaps_by_example.md- Examples of memory safety in actiongimso_semantics.md- Formal semantics documentation