wcc/check: #103/#108 inferred untyped-int defaults to int (8B), both stages
cstage type_default(TY_UNTYPED_INT) returned ty_i32 (4B): an unannotated `let x = <v>` / `let a = [<v>,..]` silently TRUNCATED any value > 2^31 (5000000000 -> 705032704) and strode inferred arrays at 4. wwstage kept the element raw untyped_int (size 0), which sized INCONSISTENTLY across cgen — the array STORE strode the 8 sentinel but letslotsize under- allocated the frame (SEGV) and cgindex strode the READ at 1. The two stages were each wrong differently; #263 polarity: cstage was the truncating side. int = machine word = 8B (Go-style, MEMORY project_int_machine_word_derived_limits); Hare lowers a flexible iconst to `int`, never a fixed i32 (ref/harec/src/types.c:835). Fix, one root, both stages (FUSE — the cs default + the ww concrete element must land together, else the inferred array is transient cs!=ww): - cmd/wcc/type.c type_default(TY_UNTYPED_INT) ty_i32 -> ty_int. The root; stops scalar AND array truncation at source. - cmd/wcc/check.c N_ARRLIT empty-elt fallback ty_i32 -> ty_int. Symmetric pair; count-0 array emits no stores, so byte-id-neutral. - selfhost/cmd/wcc/check.ww exprtype N_ARRLIT: default the inferred element's untyped flavor to concrete (untyped_int->int, _float->f64, _str->str, _rune->rune, _bool->bool, mirror cstage type_default), empty-elt "i32"->"int", and stamp the synthesized N_TARRAY's .type_ so slotsize / elemsizeofc / letslotsize read its real [N]int size via the type table (rule-13) — no letslotsize special-case (SSoT). combined.ww regen (check.ww embed): w6c + wwdump. ken v2 corpus re-census (160 files): EXACTLY 5 rows move, ALL CONVERGE (byte-id YES + run exit 0, none both-wrong, zero regression): m2_while #108 scalar via alias-bool loop m8_range1 #104 for-range elem over alias [4]int m8_range2 #104 over 2-level alias m8_slice1 #103 inferred array + alias-slice init m8_slice2 #103 + 2-level-alias slice + re-slice Bootstrap byte-id neutral (5 combined units w6c==w6c_ww; 0 bare inferred arrays in selfhost). Annotated controls untouched ([4]i32 stride-4, [4]int stride-8, byte-id). Pinned in test/wcc/813_arrlit_infer_elem_run (the 2 direct repros incl the >2^31 truncation teeth + all 5 movers + controls; test-unit 296). Closes #103 (inferred-array SEGV + truncation), #108 (cstage scalar untyped-int truncation), #104 (for-range elem alias i32-stamp), and the m8_slice []int-init acceptance divergence.
This commit is contained in:
@@ -13514,13 +13514,45 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
};
|
||||
it = it.next;
|
||||
};
|
||||
if (elt == nil) { elt = mktname(c, "i32"); };
|
||||
// #103/#108: default the inferred element's UNTYPED flavor to its
|
||||
// concrete type, mirroring cstage cmd/wcc/check.c:1856
|
||||
// `elt = type_default(t)` (type.c:237 untyped_int→int after the
|
||||
// #108 polarity flip). Keeping the raw untyped_int (the prior
|
||||
// documented divergence) sized the synthesized [N]untyped_int
|
||||
// INCONSISTENTLY — untyped_int.size is 0, so the cgarrlitfillbp
|
||||
// STORE strode the 8 sentinel while slotsize (letslotsize slot)
|
||||
// and elemsizeofc (cgindex READ stride) read the 0-size element
|
||||
// → frame under-alloc SEGV + stride-1 index reads, cs≠ww. drew
|
||||
// Hare-fidelity: harec lower_flexible defaults a flexible iconst
|
||||
// to `int` (ref/harec/src/types.c:835). int = machine word (8B);
|
||||
// the old i32 truncated values >2^31 (#263 trap).
|
||||
if (elt != nil && elt.kind == nkind.N_TNAME) {
|
||||
if (streq(elt.str, "untyped_int")) {
|
||||
elt = mktname(c, "int");
|
||||
} else { if (streq(elt.str, "untyped_float")) {
|
||||
elt = mktname(c, "f64");
|
||||
} else { if (streq(elt.str, "untyped_str")) {
|
||||
elt = mktname(c, "str");
|
||||
} else { if (streq(elt.str, "untyped_rune")) {
|
||||
elt = mktname(c, "rune");
|
||||
} else { if (streq(elt.str, "untyped_bool")) {
|
||||
elt = mktname(c, "bool");
|
||||
}; }; }; }; };
|
||||
};
|
||||
// Empty inferred arrlit: default to int, symmetric with cstage
|
||||
// check.c:1859 empty-fallback ty_int (#103). Was "i32".
|
||||
if (elt == nil) { elt = mktname(c, "int"); };
|
||||
let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0);
|
||||
arr.lhs = elt;
|
||||
let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0);
|
||||
cn.uval = count;
|
||||
arr.rhs = cn;
|
||||
e.type_ = tinfofornode(c, arr): *void;
|
||||
// #103: stamp the synthesized array NODE too. checkletassign
|
||||
// plants this node on the inferred let's n.lhs; slotsize /
|
||||
// elemsizeofc / letslotsize all read n.lhs.type_, which was nil
|
||||
// here (only e.type_ was set) — falling to the 8 / 0 sentinels.
|
||||
arr.type_ = e.type_;
|
||||
return arr;
|
||||
};
|
||||
if (k == nkind.N_SLICE) {
|
||||
|
||||
@@ -3233,13 +3233,45 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
};
|
||||
it = it.next;
|
||||
};
|
||||
if (elt == nil) { elt = mktname(c, "i32"); };
|
||||
// #103/#108: default the inferred element's UNTYPED flavor to its
|
||||
// concrete type, mirroring cstage cmd/wcc/check.c:1856
|
||||
// `elt = type_default(t)` (type.c:237 untyped_int→int after the
|
||||
// #108 polarity flip). Keeping the raw untyped_int (the prior
|
||||
// documented divergence) sized the synthesized [N]untyped_int
|
||||
// INCONSISTENTLY — untyped_int.size is 0, so the cgarrlitfillbp
|
||||
// STORE strode the 8 sentinel while slotsize (letslotsize slot)
|
||||
// and elemsizeofc (cgindex READ stride) read the 0-size element
|
||||
// → frame under-alloc SEGV + stride-1 index reads, cs≠ww. drew
|
||||
// Hare-fidelity: harec lower_flexible defaults a flexible iconst
|
||||
// to `int` (ref/harec/src/types.c:835). int = machine word (8B);
|
||||
// the old i32 truncated values >2^31 (#263 trap).
|
||||
if (elt != nil && elt.kind == nkind.N_TNAME) {
|
||||
if (streq(elt.str, "untyped_int")) {
|
||||
elt = mktname(c, "int");
|
||||
} else { if (streq(elt.str, "untyped_float")) {
|
||||
elt = mktname(c, "f64");
|
||||
} else { if (streq(elt.str, "untyped_str")) {
|
||||
elt = mktname(c, "str");
|
||||
} else { if (streq(elt.str, "untyped_rune")) {
|
||||
elt = mktname(c, "rune");
|
||||
} else { if (streq(elt.str, "untyped_bool")) {
|
||||
elt = mktname(c, "bool");
|
||||
}; }; }; }; };
|
||||
};
|
||||
// Empty inferred arrlit: default to int, symmetric with cstage
|
||||
// check.c:1859 empty-fallback ty_int (#103). Was "i32".
|
||||
if (elt == nil) { elt = mktname(c, "int"); };
|
||||
let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0);
|
||||
arr.lhs = elt;
|
||||
let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0);
|
||||
cn.uval = count;
|
||||
arr.rhs = cn;
|
||||
e.type_ = tinfofornode(c, arr): *void;
|
||||
// #103: stamp the synthesized array NODE too. checkletassign
|
||||
// plants this node on the inferred let's n.lhs; slotsize /
|
||||
// elemsizeofc / letslotsize all read n.lhs.type_, which was nil
|
||||
// here (only e.type_ was set) — falling to the 8 / 0 sentinels.
|
||||
arr.type_ = e.type_;
|
||||
return arr;
|
||||
};
|
||||
if (k == nkind.N_SLICE) {
|
||||
|
||||
@@ -13514,13 +13514,45 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
};
|
||||
it = it.next;
|
||||
};
|
||||
if (elt == nil) { elt = mktname(c, "i32"); };
|
||||
// #103/#108: default the inferred element's UNTYPED flavor to its
|
||||
// concrete type, mirroring cstage cmd/wcc/check.c:1856
|
||||
// `elt = type_default(t)` (type.c:237 untyped_int→int after the
|
||||
// #108 polarity flip). Keeping the raw untyped_int (the prior
|
||||
// documented divergence) sized the synthesized [N]untyped_int
|
||||
// INCONSISTENTLY — untyped_int.size is 0, so the cgarrlitfillbp
|
||||
// STORE strode the 8 sentinel while slotsize (letslotsize slot)
|
||||
// and elemsizeofc (cgindex READ stride) read the 0-size element
|
||||
// → frame under-alloc SEGV + stride-1 index reads, cs≠ww. drew
|
||||
// Hare-fidelity: harec lower_flexible defaults a flexible iconst
|
||||
// to `int` (ref/harec/src/types.c:835). int = machine word (8B);
|
||||
// the old i32 truncated values >2^31 (#263 trap).
|
||||
if (elt != nil && elt.kind == nkind.N_TNAME) {
|
||||
if (streq(elt.str, "untyped_int")) {
|
||||
elt = mktname(c, "int");
|
||||
} else { if (streq(elt.str, "untyped_float")) {
|
||||
elt = mktname(c, "f64");
|
||||
} else { if (streq(elt.str, "untyped_str")) {
|
||||
elt = mktname(c, "str");
|
||||
} else { if (streq(elt.str, "untyped_rune")) {
|
||||
elt = mktname(c, "rune");
|
||||
} else { if (streq(elt.str, "untyped_bool")) {
|
||||
elt = mktname(c, "bool");
|
||||
}; }; }; }; };
|
||||
};
|
||||
// Empty inferred arrlit: default to int, symmetric with cstage
|
||||
// check.c:1859 empty-fallback ty_int (#103). Was "i32".
|
||||
if (elt == nil) { elt = mktname(c, "int"); };
|
||||
let arr: *node = newnode(nkind.N_TARRAY, "", 0, 0);
|
||||
arr.lhs = elt;
|
||||
let cn: *node = newnode(nkind.N_INTLIT, "", 0, 0);
|
||||
cn.uval = count;
|
||||
arr.rhs = cn;
|
||||
e.type_ = tinfofornode(c, arr): *void;
|
||||
// #103: stamp the synthesized array NODE too. checkletassign
|
||||
// plants this node on the inferred let's n.lhs; slotsize /
|
||||
// elemsizeofc / letslotsize all read n.lhs.type_, which was nil
|
||||
// here (only e.type_ was set) — falling to the 8 / 0 sentinels.
|
||||
arr.type_ = e.type_;
|
||||
return arr;
|
||||
};
|
||||
if (k == nkind.N_SLICE) {
|
||||
|
||||
Reference in New Issue
Block a user