check: reject non-integer index operand in wwstage (catB-17)

Mirrors cstage check.c:1491-1495 (type_isint via the syntax.typeisint tinfo chaser, which chases TY_NAMED.under/TY_ENUM.sub — not the AST-keyed isinttypeast that would falsely reject an alias-int index). Record-and-continue, before the base-bail. Reject path emits no asm so cstage==wwstage byte-id holds (453 green). Pre-existing index double-emit deferred (#6).
This commit is contained in:
2026-06-20 20:12:11 +09:00
parent 7589b1bf0b
commit b9692b14f1
3 changed files with 264 additions and 2 deletions

View File

@@ -2988,14 +2988,27 @@ fn unoptype(c: *checker, e: *syntax.node) *syntax.node = {
};
// indexresult — derive the result tnode of an N_INDEX expression.
// Mirrors cstage cmd/wcc/check.c:870-894 and harec ref/harec/src/types.c
// Mirrors cstage cmd/wcc/check.c:1491-1535 (N_INDEX arm) and harec ref/harec/src/types.c
// type_promote dispatch. Slice/array → elem; str → u8; `*[N]T` decays
// to T (pointer-to-array); `*[]T` does NOT decay (yields []T via the
// generic *U → U fallback — Hare-faithful, a pointer-to-slice is a 1D
// array of slices, not of T); generic *T → T.
fn indexresult(c: *checker, e: *syntax.node) *syntax.node = {
let basetn: *syntax.node = exprtype(c, e.lhs, nil);
let _idx: *syntax.node = exprtype(c, e.rhs, nil);
let idxtn: *syntax.node = exprtype(c, e.rhs, nil);
// cstage cmd/wcc/check.c:1491-1495: index operand must be integer.
// typeisint is the tinfo chaser (follows TY_ENUM.sub / TY_NAMED.under),
// so an alias-int or named-enum index passes; the AST-keyed isinttypeast
// would falsely reject `type ix = i32`. Both nil-guards mirror cstage's
// `idx != ty_err` cascade-suppression so a broken subexpr emits one error.
if (idxtn != nil) {
let it: *syntax.tinfo = tinfofornode(c, idxtn);
if (it != nil && !syntax.typeisint(it)) {
cerr(e.file);
cerr(": error: index must be integer\n");
c.errs += 1;
};
};
let u: *syntax.node = resolvealias(c, unwrapbang(basetn));
// basetn nil → propagation from inherent-IDENT bail at exprtype
// N_IDENT arm L1596-1599 (5-lite-b #34, A.6.2.1c #24).