v2.8.20
Fix: return N from main was silently ignored.
The auto-inserted exit syscall at the end of main was clobbering the return register (rax on x86_64, x0 on aarch64) with a hardcoded 0 right before the syscall, so:
```kernrift
fn main() -> int32 { return 42 }
```
exited with status 0 instead of 42 — on every backend (legacy and IR, both arches). The user-visible symptom was that while 1 == 1 { if cond { return 42 } } ignored the return, but it was the same root cause; the loop had nothing to do with it. Existing examples like hello.kr were fine because they call exit(0) explicitly and never reach the auto-glue.
Fix:
- Auto-exit syscall now forwards the current
rax/x0as the exit code. IR_RET_VOIDzerosrax/x0before branching to the epilogue, sofn main() { ... }(void) still exits with0.- Legacy backends do the same zero at the start of
main's body. - Function-local
return(in non-mainfunctions) is unaffected: callers don't read the return register on void returns.
Verified:
fn main() -> int32 { return 42 }→ exit 42 ✓while 1 == 1 { ...; return 7 }→ exit 7 ✓while 1 == 1 { println(i); if i == 3 { return 42 } }→ prints1 2 3, exit 42 ✓fn main() { ... }(void) → exit 0 ✓
Bootstrap fixed point at 1,244,072 bytes; 439/439 tests pass.
Full Changelog: v2.8.19...v2.8.20
Full Changelog: v2.8.19...v2.8.20