wcc: nodeisunsigned N_INDEX reads stamped type_ (#134)
wwstage cgenutil nodeisunsigned N_INDEX arm now reads typeisunsigned(n.type_) directly, mirroring the N_DOT arm at line 1007 and cstage cgen.c:2541 which reads type_isunsigned on the stamped operand. Embodies the #121 principle (collapse structural onto stamp). Byte-id-neutral at master (no current N_INDEX-of-non- IDENT-base unsigned compare sites in bootstrap); fix is for forward consumers in strconv decimal.ha (>= 5u8 on d.digits[nd] with N_DOT base) and similar Hare idioms. Closes #134.
This commit is contained in:
@@ -12028,31 +12028,18 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = {
|
|||||||
return nodeisunsigned(c, n.rhs);
|
return nodeisunsigned(c, n.rhs);
|
||||||
};
|
};
|
||||||
if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); };
|
if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); };
|
||||||
// nkind.N_INDEX: `p[i]` is unsigned iff p's element type is unsigned.
|
// nkind.N_INDEX: `p[i]` is unsigned iff its element type is
|
||||||
// Walks the base local's declared type and pulls the element
|
// unsigned. Read the checker-stamped result type directly,
|
||||||
// out — *u8 → u8, [N]u32 → u32, []u64 → u64. Without this the
|
// mirroring the N_DOT arm above and cstage cgen.c:2541
|
||||||
// compare-codegen for `p[i] >= 48u8` falls back to signed JGE
|
// (`type_isunsigned(n->lhs->type)` on operand's stamped tinfo).
|
||||||
// instead of JAE, diverging from C w6c on byte indexing.
|
// 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) {
|
if (k == nkind.N_INDEX) {
|
||||||
let base: *node = n.lhs;
|
return typeisunsigned(n.type_: *tinfo);
|
||||||
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 false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1015,31 +1015,18 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = {
|
|||||||
return nodeisunsigned(c, n.rhs);
|
return nodeisunsigned(c, n.rhs);
|
||||||
};
|
};
|
||||||
if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); };
|
if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); };
|
||||||
// nkind.N_INDEX: `p[i]` is unsigned iff p's element type is unsigned.
|
// nkind.N_INDEX: `p[i]` is unsigned iff its element type is
|
||||||
// Walks the base local's declared type and pulls the element
|
// unsigned. Read the checker-stamped result type directly,
|
||||||
// out — *u8 → u8, [N]u32 → u32, []u64 → u64. Without this the
|
// mirroring the N_DOT arm above and cstage cgen.c:2541
|
||||||
// compare-codegen for `p[i] >= 48u8` falls back to signed JGE
|
// (`type_isunsigned(n->lhs->type)` on operand's stamped tinfo).
|
||||||
// instead of JAE, diverging from C w6c on byte indexing.
|
// 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) {
|
if (k == nkind.N_INDEX) {
|
||||||
let base: *node = n.lhs;
|
return typeisunsigned(n.type_: *tinfo);
|
||||||
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 false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12028,31 +12028,18 @@ fn nodeisunsigned(c: *cgen, n: *node) bool = {
|
|||||||
return nodeisunsigned(c, n.rhs);
|
return nodeisunsigned(c, n.rhs);
|
||||||
};
|
};
|
||||||
if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); };
|
if (k == nkind.N_UN) { return nodeisunsigned(c, n.lhs); };
|
||||||
// nkind.N_INDEX: `p[i]` is unsigned iff p's element type is unsigned.
|
// nkind.N_INDEX: `p[i]` is unsigned iff its element type is
|
||||||
// Walks the base local's declared type and pulls the element
|
// unsigned. Read the checker-stamped result type directly,
|
||||||
// out — *u8 → u8, [N]u32 → u32, []u64 → u64. Without this the
|
// mirroring the N_DOT arm above and cstage cgen.c:2541
|
||||||
// compare-codegen for `p[i] >= 48u8` falls back to signed JGE
|
// (`type_isunsigned(n->lhs->type)` on operand's stamped tinfo).
|
||||||
// instead of JAE, diverging from C w6c on byte indexing.
|
// 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) {
|
if (k == nkind.N_INDEX) {
|
||||||
let base: *node = n.lhs;
|
return typeisunsigned(n.type_: *tinfo);
|
||||||
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 false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user