Every section banner dies (103 -> 0) across test/lang, the observer suites, the C carriers, and the five comment-heavy corpus fixtures; banner provenance (#N cites, carrier numbers, repair-cluster labels) folded into headers or adjacent WHY comments. Narration deleted; row provenance, ref cites, divergence pins, and layout contracts kept (fwd-ref decl-order guards and bootstrap-gate corpus rationale restored where the sweep over-cut). Comment-only proven: all 3742 wwbuild workdir .s byte-identical before/after; test-commit and test-byteid (161 lang + 1399 data, 0 pinned-divergent) green.
213 lines
6.0 KiB
Plaintext
213 lines
6.0 KiB
Plaintext
// #5 alias arc F2a batch 1 (task #60 + #79 init-store
|
|
// rider): wwstage INDEX / SLICE / FOR-RANGE / LITERAL-INIT over an alias-NAMED
|
|
// base type, migrated from test/wcc/944_alias_idx_family_run.c (#5-C3). The
|
|
// tnode-keyed cgen walks saw only the N_TNAME leaf — esz fell to the
|
|
// 1-sentinel and the base classified as a POINTER (MOVQ + no IMULQ): SEGV on
|
|
// index/range, silent-wrong on slice, alias-[N]u32 literal-init stride-skew
|
|
// (#79). cstage reads everything off the chased stamped type and is the
|
|
// runtime-correct reference; the fix re-keys the ww sites off tichase'd
|
|
// tinfos and every row graduates to byte-id (ww aligned UP).
|
|
//
|
|
// Values exceed 255 so an esz=1 byte-load cannot pass by little-endian
|
|
// prefix-luck; readbacks assert the LAST element. The C driver ran each row
|
|
// on both stages + asserted cs==ww exit; here the cstage run is test-lang (T1)
|
|
// and the byte-id is test-lang-byteid (T2). The fwd-ref rows' decl-order
|
|
// dimension is subsumed by module-level resolution (already order-independent).
|
|
//
|
|
// Deliberately NOT pinned (g-fold #77/#78): any DIRECT alias-typed global
|
|
// ARRAY row (ww link-ERR / cs silent-wrong) — m7c_global2d's alias is on the
|
|
// ELEMENT and gslice_alias is a global alias SLICE, both of which resolve.
|
|
|
|
package alias_idx_family_test;
|
|
|
|
type arr = [4]int;
|
|
type arr2 = arr;
|
|
type sl = []int;
|
|
type sl2 = sl;
|
|
type a4 = [4]u32;
|
|
type a6 = [6]u32;
|
|
type arrk = [1024]int;
|
|
type slk = []int;
|
|
type slk2 = slk;
|
|
type row = [3]int;
|
|
|
|
let g_2d: [2]row = [[10: int, 20: int, 30: int], [40: int, 50: int, 60: int]];
|
|
let g_slice: sl = [1000: int, 2000: int, 3000: int];
|
|
|
|
@test fn idx0_ctl() void = {
|
|
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
assert(a[3] == 4000);
|
|
a[3] = 9999;
|
|
assert(a[3] == 9999);
|
|
};
|
|
|
|
@test fn idx1_alias() void = {
|
|
let a: arr = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
assert(a[2] == 3000);
|
|
assert(a[3] == 4000);
|
|
a[3] = 8888;
|
|
assert(a[3] == 8888);
|
|
};
|
|
|
|
@test fn idx2_2level() void = {
|
|
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
assert(a[2] == 3000);
|
|
a[1] = 9999;
|
|
assert(a[1] == 9999);
|
|
assert(a[3] == 4000);
|
|
};
|
|
|
|
@test fn idx_fwdref() void = {
|
|
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
assert(a[3] == 4000);
|
|
a[3] += 500;
|
|
assert(a[3] == 4500);
|
|
};
|
|
|
|
// #79: narrow-elem alias literal-init — pre-fix the per-element store rode the
|
|
// esz=8 sentinel + MOVQ over a stride-4 slot (saved-BP/RIP smash); LAST read.
|
|
@test fn init_u32_alias() void = {
|
|
let a: a4 = [1: u32, 2: u32, 3: u32, 4: u32];
|
|
assert(a[3] == 4);
|
|
assert(a[0] == 1);
|
|
};
|
|
|
|
@test fn initrep_u32_alias() void = {
|
|
let a: a6 = [7: u32...];
|
|
assert(a[5] == 7);
|
|
assert(a[0] == 7);
|
|
};
|
|
|
|
// uninit alias array + per-index loop fill; pins the bare-let classify (no
|
|
// composite zero-fill, cstage-identical).
|
|
@test fn loopfill_1024() void = {
|
|
let a: arrk;
|
|
let i: int = 0;
|
|
for (i < 1024) {
|
|
a[i] = i * 3 + 1000;
|
|
i += 1;
|
|
};
|
|
assert(a[1023] == 1023 * 3 + 1000);
|
|
};
|
|
|
|
@test fn slice0_ctl() void = {
|
|
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let s: []int = a[1:3];
|
|
assert(s.len == 2);
|
|
assert(s[1] == 3000);
|
|
};
|
|
|
|
@test fn slice1_alias() void = {
|
|
let a: arr = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let s: sl = a[1:3];
|
|
assert(s.len == 2);
|
|
assert(s[0] == 2000);
|
|
s[1] = 7777;
|
|
assert(a[2] == 7777);
|
|
};
|
|
|
|
@test fn slice2_2level() void = {
|
|
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let s: sl2 = a[1:3];
|
|
assert(s.len == 2);
|
|
assert(s[0] == 2000);
|
|
s[1] = 7777;
|
|
assert(a[2] == 7777);
|
|
assert(s[1] == 7777);
|
|
let r: sl = s[0:2];
|
|
assert(r.len == 2);
|
|
assert(r[1] == 7777);
|
|
};
|
|
|
|
// 1000 elements, values 300..7293: an esz=1 byte load cannot land on the right
|
|
// word; LAST-elem readback breaks prefix-luck. Also pins alias default-hi
|
|
// (a[2:]), .cap via the chased cgbasecap leg, and range over the sub-slice.
|
|
@test fn slice1big() void = {
|
|
let a: [1000]int;
|
|
let i: int = 0;
|
|
for (i < 1000) {
|
|
a[i] = i * 7 + 300;
|
|
i += 1;
|
|
};
|
|
let s: slk = a[1:1000];
|
|
assert(s.len == 999);
|
|
assert(s[998] == 999 * 7 + 300);
|
|
s[998] = 123456;
|
|
assert(a[999] == 123456);
|
|
let t: slk2 = a[2:];
|
|
assert(t.len == 998);
|
|
assert(t.cap == 998);
|
|
assert(t[997] == 123456);
|
|
let cnt: int = 0;
|
|
for (let x .. t) { cnt = cnt + 1; assert(x >= 0); };
|
|
assert(cnt == 998);
|
|
};
|
|
|
|
@test fn slice_fwdref() void = {
|
|
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let s: sl2 = a[1:3];
|
|
assert(s[1] == 3000);
|
|
s[1] *= 3;
|
|
assert(a[2] == 9000);
|
|
};
|
|
|
|
@test fn range0_ctl() void = {
|
|
let a: [4]int = [1: int, 2: int, 3: int, 4: int];
|
|
let sum: int = 0;
|
|
for (let x .. a) { sum = sum + x; };
|
|
assert(sum == 10);
|
|
};
|
|
|
|
@test fn range1_alias() void = {
|
|
let a: arr = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let sum: int = 0;
|
|
for (let x .. a) { sum = sum + x; };
|
|
assert(sum == 10000);
|
|
};
|
|
|
|
@test fn range2_2level() void = {
|
|
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let sum: int = 0;
|
|
for (let x .. a) { sum = sum + x; };
|
|
assert(sum == 10000);
|
|
};
|
|
|
|
@test fn range_slicealias() void = {
|
|
let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let t: sl = a[0:4];
|
|
let sum: int = 0;
|
|
for (let x .. t) { sum = sum + x; };
|
|
assert(sum == 10000);
|
|
};
|
|
|
|
// m7c: the BASE is a plain [2]row global — the alias sits on the ELEMENT
|
|
// (row = [3]int). elemisarrayc's node walk can't see through the element's
|
|
// N_TNAME, so g[0] loaded a VALUE where the sub-array ADDRESS was needed.
|
|
@test fn m7c_global2d() void = {
|
|
assert(g_2d[0][0] == 10);
|
|
assert(g_2d[1][2] == 60);
|
|
};
|
|
|
|
// GLOBAL alias-typed SLICE: DATA emit + .len + indexed read all resolve.
|
|
@test fn gslice_alias() void = {
|
|
assert(g_slice.len == 3);
|
|
assert(g_slice[2] == 3000);
|
|
};
|
|
|
|
// slice-of-alias-array as a CALL ARG exercises the pusharg N_SLICE leg, a
|
|
// distinct lowering from cgslice; plus inferred-let receive of an alias-base
|
|
// slice.
|
|
fn sumof(s: []int) int = {
|
|
let t: int = 0;
|
|
for (let x .. s) { t = t + x; };
|
|
return t;
|
|
};
|
|
|
|
@test fn slicearg_alias() void = {
|
|
let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];
|
|
let s = a[1:3];
|
|
assert(s.len == 2);
|
|
assert(s[1] == 3000);
|
|
assert(sumof(a[0:4]) == 10000);
|
|
};
|