fix(lower): drop dead statements after a return/raise terminator (issue 0061)

A bare `return X;` / `raise` in the middle of a block closed the current
LLVM basic block, but lowerBlock / lowerBlockValue only stopped the
statement loop on the `block_terminated` flag — which lowerReturn
deliberately never sets (it would leak past an `if cond { return }` merge
block). So trailing dead statements were emitted into the already-closed
block, tripping the LLVM verifier with "Terminator found in the middle of
a basic block".

Fix: also stop the statement loop when currentBlockHasTerminator() is
true. That is CFG-level termination of the *current* block, which is
naturally false at an if / inline-if merge block, so conditional returns
still fall through to their trailing statements.

This unblocks ERR E5.1: the canonical failable-closure form
`closure((x) -> (s32,!) { raise error.X; return x; })` has a dead
`return x;` after the unconditional raise and tripped the verifier.

Regression: examples/0038-basic-dead-code-after-terminator.sx.
This commit is contained in:
agra
2026-06-01 21:42:20 +03:00
parent b113e03fa3
commit 0e1afa3eba
6 changed files with 119 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
const_one=1
raised=0
clamp_hi=10
clamp_lo=7