w6c+selfhost: cgen && and || short-circuit

Both stages were eagerly evaluating RHS regardless of LHS (eager
ANDQ/ORQ on the two results). Now: eval LHS into AX, CMPQ $0 +
JE/JNE to a per-call-site label, eval RHS into AX, fall through.
AX holds the LHS sentinel on the skipped path — typechecker
already enforces bool operands.

Surfaced by lib/getopt's nil-argv guard segfault. Six new rows in
test/wcc/700_e2e.c, three of which segfault pre-fix. lib/getopt
test comment relaxed; nested-if kept as regression marker.
This commit is contained in:
2026-05-13 19:21:43 +09:00
parent fbe0df4e68
commit 5bfdc7b20d
6 changed files with 141 additions and 18 deletions

View File

@@ -14,10 +14,10 @@
// path uses MOVL and avoids the over-read.
//
// Guards on a possibly-nil [[command.argsptr]] are split into nested
// `if`s rather than `argslen > 0 && !streq(argsptr[0], ...)`: the
// cstage cgen evaluates the RHS of `&&` even when the LHS is false,
// segfaulting on the nil deref when tryparse exits with no positional
// args (e.g. `["ls", "--"]`).
// `if`s rather than `argslen > 0 && !streq(argsptr[0], ...)`. The
// flattened `&&` form is now legal — both cgen stages short-circuit
// per task #15 — but the nested-if shape was the original workaround
// and is preserved here as a regression marker.
use getopt;
use strings;