// #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); };