diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index c98ab225..9b6a5fea 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -12028,31 +12028,18 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { return nodeisunsigned(c, n.rhs); }; if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; - // nkind.N_INDEX: `p[i]` is unsigned iff p's element type is unsigned. - // Walks the base local's declared type and pulls the element - // out — *u8 → u8, [N]u32 → u32, []u64 → u64. Without this the - // compare-codegen for `p[i] >= 48u8` falls back to signed JGE - // instead of JAE, diverging from C w6c on byte indexing. + // nkind.N_INDEX: `p[i]` is unsigned iff its element type is + // unsigned. Read the checker-stamped result type directly, + // mirroring the N_DOT arm above and cstage cgen.c:2541 + // (`type_isunsigned(n->lhs->type)` on operand's stamped tinfo). + // Replaces the prior structural base-walk that only fired for + // N_IDENT base — fell through to `return false` for N_DOT base + // (e.g. `d.digits[nd]` where d is a *struct), making + // `d.digits[nd] >= 5u8` pick signed JGE instead of unsigned JAE. + // Embodies the #121 principle (collapse structural onto stamp). + // #134. if (k == nkind.N_INDEX) { - let base: *node = n.lhs; - if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let lc: *local = localfindnode(c, base.str); - if (lc != nil) { - let tn: *node = lc.tnode; - if (tn != nil) { - let elem: *node = nil; - if (tn.kind == nkind.N_TPTR) { elem = tn.lhs; }; - if (tn.kind == nkind.N_TARRAY) { elem = tn.lhs; }; - if (tn.kind == nkind.N_TSLICE) { elem = tn.lhs; }; - if (elem != nil) { - return typeisunsigned(elem.type_: *tinfo); - }; - }; - }; - }; - }; - return false; + return typeisunsigned(n.type_: *tinfo); }; return false; }; diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index 1384dab4..bfeb1cfb 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -1015,31 +1015,18 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { return nodeisunsigned(c, n.rhs); }; if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; - // nkind.N_INDEX: `p[i]` is unsigned iff p's element type is unsigned. - // Walks the base local's declared type and pulls the element - // out — *u8 → u8, [N]u32 → u32, []u64 → u64. Without this the - // compare-codegen for `p[i] >= 48u8` falls back to signed JGE - // instead of JAE, diverging from C w6c on byte indexing. + // nkind.N_INDEX: `p[i]` is unsigned iff its element type is + // unsigned. Read the checker-stamped result type directly, + // mirroring the N_DOT arm above and cstage cgen.c:2541 + // (`type_isunsigned(n->lhs->type)` on operand's stamped tinfo). + // Replaces the prior structural base-walk that only fired for + // N_IDENT base — fell through to `return false` for N_DOT base + // (e.g. `d.digits[nd]` where d is a *struct), making + // `d.digits[nd] >= 5u8` pick signed JGE instead of unsigned JAE. + // Embodies the #121 principle (collapse structural onto stamp). + // #134. if (k == nkind.N_INDEX) { - let base: *node = n.lhs; - if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let lc: *local = localfindnode(c, base.str); - if (lc != nil) { - let tn: *node = lc.tnode; - if (tn != nil) { - let elem: *node = nil; - if (tn.kind == nkind.N_TPTR) { elem = tn.lhs; }; - if (tn.kind == nkind.N_TARRAY) { elem = tn.lhs; }; - if (tn.kind == nkind.N_TSLICE) { elem = tn.lhs; }; - if (elem != nil) { - return typeisunsigned(elem.type_: *tinfo); - }; - }; - }; - }; - }; - return false; + return typeisunsigned(n.type_: *tinfo); }; return false; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 42f9e4ac..2fdd2de6 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -12028,31 +12028,18 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = { return nodeisunsigned(c, n.rhs); }; if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); }; - // nkind.N_INDEX: `p[i]` is unsigned iff p's element type is unsigned. - // Walks the base local's declared type and pulls the element - // out — *u8 → u8, [N]u32 → u32, []u64 → u64. Without this the - // compare-codegen for `p[i] >= 48u8` falls back to signed JGE - // instead of JAE, diverging from C w6c on byte indexing. + // nkind.N_INDEX: `p[i]` is unsigned iff its element type is + // unsigned. Read the checker-stamped result type directly, + // mirroring the N_DOT arm above and cstage cgen.c:2541 + // (`type_isunsigned(n->lhs->type)` on operand's stamped tinfo). + // Replaces the prior structural base-walk that only fired for + // N_IDENT base — fell through to `return false` for N_DOT base + // (e.g. `d.digits[nd]` where d is a *struct), making + // `d.digits[nd] >= 5u8` pick signed JGE instead of unsigned JAE. + // Embodies the #121 principle (collapse structural onto stamp). + // #134. if (k == nkind.N_INDEX) { - let base: *node = n.lhs; - if (base != nil) { - if (base.kind == nkind.N_IDENT) { - let lc: *local = localfindnode(c, base.str); - if (lc != nil) { - let tn: *node = lc.tnode; - if (tn != nil) { - let elem: *node = nil; - if (tn.kind == nkind.N_TPTR) { elem = tn.lhs; }; - if (tn.kind == nkind.N_TARRAY) { elem = tn.lhs; }; - if (tn.kind == nkind.N_TSLICE) { elem = tn.lhs; }; - if (elem != nil) { - return typeisunsigned(elem.type_: *tinfo); - }; - }; - }; - }; - }; - return false; + return typeisunsigned(n.type_: *tinfo); }; return false; };