// idx_dot_src_aggregate_test — #11b: a NON-call AGGREGATE source assigned into // an AGGREGATE field of an INDEXED element `arr[i].f = src` (src an ident or a // field `.g`, NOT a function call). Pre-fix the N_DOT(N_INDEX) assign arm had no // aggregate-source case: it fell to the 1-word scalar default — cgexpr loaded // only the source's FIRST word into AX and stored ONE word, dropping the rest. // BOTH stages emitted byte-IDENTICAL wrong asm (gate-blind, the #263 both-wrong // form) — the non-call twin of #11 (idx_dot_aggret_recv_test, the in-cap CALL // source). Unlike #11's GP AX/DX/CX cursor, the source here is a MEMORY address, // so the shared mem-to-mem aggcopy transports EVERY byte — a sub-8 tail (MOVL/ // MOVW/MOVB) and float bits copy verbatim, so the fix needs NO tail/float/over- // cap loud-stop (those #11 stops were register-cursor artefacts). Each @test // POISON-seeds the field + its neighbour with sentinel 9 (distinct from 0 AND // every expected value) and asserts EVERY member: a dropped word reads 9 and // fails. Covers IDENT and DOT sources, full=2/full=3 (CX word), the sub-8-tail // MOVL row (anti-clobber: the 12B field's tail MUST stay MOVL — a widened MOVQ // would smash the adjacent g at +12), foff!=0, a float-bearing field, and bases // [N]S / *[N]S / []S with const + runtime index. The sub-8-tail rows use a // GLOBAL-backed base: a LOCAL [N] array trips a SEPARATE // PRE-EXISTING let-array slotsize cs!=ww FRAME divergence (see the _runonly // twin; task #9), independent of #11b. T2 keeps the cs==ww net. package idx_dot_src_aggregate_test; type t16 = struct { a: i64, b: i64 }; type t24 = struct { a: i64, b: i64, c: i64 }; type t12 = struct { a: i32, b: i32, c: i32 }; type ft = struct { x: f64, y: i64 }; type s16 = struct { f: t16, g: i64 }; type s24 = struct { f: t24, g: i64 }; type sfnf = struct { g: i64, f: t16 }; type sf = struct { f: ft, g: i64 }; type s12 = struct { f: t12, g: i32 }; type w16 = struct { pad: i64, inner: t16 }; type w12 = struct { pad: i64, inner: t12 }; let g12p: [2]s12 = [s12{f=t12{a=9i32,b=9i32,c=9i32},g=9i32}, s12{f=t12{a=9i32,b=9i32,c=9i32},g=9i32}]; let g12s: [2]s12 = [s12{f=t12{a=9i32,b=9i32,c=9i32},g=9i32}, s12{f=t12{a=9i32,b=9i32,c=9i32},g=9i32}]; let g12d: [2]s12 = [s12{f=t12{a=9i32,b=9i32,c=9i32},g=9i32}, s12{f=t12{a=9i32,b=9i32,c=9i32},g=9i32}]; // full=2, [N]S value-array local, IDENT src, const index, foff=0 @test fn struct16_local_ident_const() void = { let a: [2]s16 = [s16{f=t16{a=9i64,b=9i64},g=9i64}, s16{f=t16{a=9i64,b=9i64},g=9i64}]; let src: t16 = t16{a=40i64, b=20i64}; a[1].f = src; assert(a[1].f.a == 40i64); assert(a[1].f.b == 20i64); assert(a[1].g == 9i64); assert(a[0].f.a == 9i64); }; // full=2, [N]S local, DOT src (`w.inner`), const index, foff=0 @test fn struct16_local_dot_const() void = { let a: [2]s16 = [s16{f=t16{a=9i64,b=9i64},g=9i64}, s16{f=t16{a=9i64,b=9i64},g=9i64}]; let w: w16 = w16{pad=7i64, inner=t16{a=40i64, b=20i64}}; a[1].f = w.inner; assert(a[1].f.a == 40i64); assert(a[1].f.b == 20i64); assert(a[1].g == 9i64); }; // full=3 (CX word), [N]S local, IDENT src, runtime index, foff=0 @test fn struct24_local_ident_runtime() void = { let a: [2]s24 = [s24{f=t24{a=9i64,b=9i64,c=9i64},g=9i64}, s24{f=t24{a=9i64,b=9i64,c=9i64},g=9i64}]; let src: t24 = t24{a=100i64, b=20i64, c=3i64}; a[one()].f = src; assert(a[1].f.a == 100i64); assert(a[1].f.b == 20i64); assert(a[1].f.c == 3i64); assert(a[1].g == 9i64); }; // foff != 0 (f at offset 8), [N]S local, IDENT src, const index @test fn fnotfirst_local_ident() void = { let a: [2]sfnf = [sfnf{g=9i64,f=t16{a=9i64,b=9i64}}, sfnf{g=9i64,f=t16{a=9i64,b=9i64}}]; let src: t16 = t16{a=40i64, b=20i64}; a[1].f = src; assert(a[1].f.a == 40i64); assert(a[1].f.b == 20i64); assert(a[1].g == 9i64); }; // float-bearing field (mem-to-mem copies float bits verbatim — no loud-stop), // [N]S local, IDENT src, const index @test fn float_local_ident() void = { let a: [2]sf = [sf{f=ft{x=9.0f64,y=9i64},g=9i64}, sf{f=ft{x=9.0f64,y=9i64},g=9i64}]; let src: ft = ft{x=1.5f64, y=7i64}; a[1].f = src; assert(a[1].f.x == 1.5f64); assert(a[1].f.y == 7i64); assert(a[1].g == 9i64); }; // sub-8-tail (12B, MOVL tail), IDENT src, *[N]S -> global, const index @test fn subtail_ptr_ident_const() void = { let p: *[2]s12 = &g12p; let src: t12 = t12{a=10i32, b=20i32, c=30i32}; p[1].f = src; assert(g12p[1].f.a == 10i32); assert(g12p[1].f.b == 20i32); assert(g12p[1].f.c == 30i32); assert(g12p[1].g == 9i32); }; // sub-8-tail (12B, MOVL tail), IDENT src, []S -> global, runtime index @test fn subtail_slice_ident_runtime() void = { let sl: []s12 = g12s[0:2]; let src: t12 = t12{a=10i32, b=20i32, c=30i32}; sl[one()].f = src; assert(g12s[1].f.a == 10i32); assert(g12s[1].f.b == 20i32); assert(g12s[1].f.c == 30i32); assert(g12s[1].g == 9i32); }; // INDEX src (`srcarr[0]`), [N]S local, const index, foff=0 @test fn struct16_local_index_src() void = { let a: [2]s16 = [s16{f=t16{a=9i64,b=9i64},g=9i64}, s16{f=t16{a=9i64,b=9i64},g=9i64}]; let srcarr: [2]t16 = [t16{a=40i64, b=20i64}, t16{a=99i64, b=99i64}]; a[1].f = srcarr[0]; assert(a[1].f.a == 40i64); assert(a[1].f.b == 20i64); assert(a[1].g == 9i64); }; // sub-8-tail (12B, MOVL tail), DOT src (`w.inner`), *[N]S -> global, const index @test fn subtail_ptr_dot_const() void = { let p: *[2]s12 = &g12d; let w: w12 = w12{pad=7i64, inner=t12{a=10i32, b=20i32, c=30i32}}; p[1].f = w.inner; assert(g12d[1].f.a == 10i32); assert(g12d[1].f.b == 20i32); assert(g12d[1].f.c == 30i32); assert(g12d[1].g == 9i32); }; fn one() i64 = { return 1i64; };