Skip to content

Clear the error channel when a fallible Void function falls through - #443

Open
U0001F3A2 wants to merge 1 commit into
vercel-labs:mainfrom
U0001F3A2:fix/fallible-void-fallthrough
Open

U0001F3A2 wants to merge 1 commit into
vercel-labs:mainfrom
U0001F3A2:fix/fallible-void-fallthrough

Conversation

@U0001F3A2

Copy link
Copy Markdown

Fixes #436.

Problem

A fallible Void function that ends without return left the last value in rax (x0 on arm64). Callers read rax >> 32 as the error code, so any leftover value with non-zero high 32 bits looked like a raised error. The explicit valueless return already clears it (emit_elf64.c:3899), but the fall-through path didn't.

Fix

Emit the same clear on the fall-through path when fun->raises, in emit_elf64.c, emit_macho_x64.c and emit_macho64.c. The other backends reject check/raise today, so they can't reach this path.

conformance/native/pass/fallible-void-fallthrough.0 covers an empty body, a local, a parameter (2^32 and -1), a mutref field store, an inferred error set, and a genuine raise that must still propagate. It's registered with assertDirectRuntimeRequired. assertDirectRuntimeOrUnsupported and run_native_or_gap both treat a non-zero exit as a backend gap, so neither could have caught this.

The new lines push emit_elf64.c and emit_macho_x64.c past their compiler-metrics line budgets, so those are bumped to the new counts.

Verification

  • linux-x64 (WSL). Running the fixture through the assertDirectRuntimeRequired build/run sequence exits 1 with no output on 7e1a64d, and prints fallible void fallthrough ok with this change. Each case also fails on its own without the fix.
  • Existing programs with fallible helpers (examples/fallibility, direct-raises-basic, direct-rescue-basic, checked-fallible-wrapper, world-output-helper) behave the same. No size budget or snapshot moves.
  • compiler-metrics.mts and graph-input-policy.mts pass.
  • Mach-O x86-64 and arm64 checked from the emitted bytes only. I don't have a Mac to run them.
  • I couldn't run pnpm run conformance locally (no node 24 or pnpm here, and the musl runtime-linked builds need zig), so the full suite is down to CI.

Not in this PR. ELF only skips the fall-through epilogue after RETURN, while Mach-O also skips it after RAISE, so ELF emits a dead xor; leave; ret after a trailing raise. It's harmless, and I left it alone to keep this small.

🤖 Generated with Claude Code

A fallible Void function that ends without `return` left the last value in
rax (x0 on arm64). Callers read rax[63:32] as the error code, so any value
with non-zero high bits looked like a raised error. Emit the same clear the
explicit valueless return already uses on the ELF x86-64, Mach-O x86-64 and
Mach-O arm64 fall-through paths.

Add a runtime-required conformance fixture that covers empty, local,
parameter, mutref-store and inferred-error-set bodies plus a genuine raise,
and bump the emitter line budgets in compiler-metrics.

Fixes vercel-labs#436

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 19, 2026

Copy link
Copy Markdown

@U0001F3A2 is attempting to deploy a commit to the Vercel Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fallible Void function that falls off the end returns a spurious error (stale rax)

1 participant