Restore CI step: Ensure V2 can be compiled with -autofree #30
The CI step Ensure V can be compiled with -autofree in .github/workflows/other_ci.yml (./v -autofree cmd/v) has been temporarily commented out because -autofree produces a compiler that cannot reliably self-compile or compile non-trivial programs.
Current status
v_af (a cmd/v build with -autofree) can compile a trivial hello world end-to-end, but aborts with double-free / use-after-free errors on programs that exercise more parser paths (e.g. struct + method + array).
Several distinct autofree-codegen bugs surface in sequence:
- Shared sub-buffers via shallow array push — e.g.
params << params_tandfor attr in attrs { p.attrs << attr }. The destination's elements share string buffers with the source; freeing both at scope end double-frees. - Non-owning pointer locals — e.g.
for sc := s; true; sc = sc.parent { ... }.scis a non-owning&Scope, but autofree generatesScope_free(sc)becauseScopehas a user-definedfree()method. - Sumtype payload double-free — auto-generated sumtype
_freecalls_v_freeon the heap-boxed variant pointer, but the same pointer is shared across copies of the sumtype value (e.g.empty_scope_objectreferenced by every default-constructedIdent.obj). - Pointer struct fields treated as owned —
gen_free_for_structrecursively frees fields like&Scope, but pointer fields in V are conventionally non-owning, so this corrupts shared state. - Locals leaked into globals/struct fields — e.g.
lines_cache.lines[path] = lines,p.table.module_attrs[p.mod] = module_attrs,&ast.File{stmts: stmts.clone()}— autofree of the local frees buffers still referenced through the leak target.
What's needed
Each fix here is partial — every bug fixed exposes a deeper one. A more principled approach is needed than the current shallow-detection patches:
- A real ownership model in
-autofree(escape analysis for locals stored into external storage) - Idempotent
_freefor shared types (Scope, sumtype payloads, etc.) - Don't auto-emit
_freefor pointer struct fields by default - Don't
_v_freethe variant box inside auto-generated sumtype_free
Reproducer
./v -o v_af -autofree cmd/v
echo 'fn main() { println("hi") }' > /tmp/h.v
./v_af -o /tmp/h /tmp/h.v # works
cat > /tmp/t.v << 'V'
struct Point { x int y int }
fn (p Point) sum() int { return p.x + p.y }
fn main() {
p := Point{x: 1, y: 2}
println('sum: \${p.sum()}')
}
V
./v_af -o /tmp/t /tmp/t.v # aborts with double-free during parsing
Re-enable the CI step once a self-compiled v_af can compile a representative subset of programs (e.g. examples/tetris, option_test.c.v) without aborts.
[!NOTE] You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.