MODULE ArrRecFieldOpenArray; (* Repro: an array field of an array-of-record element passed as an open array actual. The field's descriptor length word is never initialized in the static array-of-record data, so the callee reads length 0 and traps. V3-built compilers miscompile this; gm2-built ones happen to work. Expected: exit 0. Actual (buggy V3): SIGABRT (134). Status (2026-10-08): FIXED for record arrays whose data is at most 131072 bytes — `QbeGen.ArrBodyItems`/`ArrData` now expand record/ class elements per element (predicate `HasArrayField`, not just nested ARRAY OF ARRAY) so each inline array field's length word is initialised. This case used to be a single zero blob, so the field's count stayed 0 and the callee trapped. Regression: compiler/tests/ t_arrrecfld.mod (exit 42). Larger tables (e.g. AST.arena, 262144 records) keep the compact zero blob on purpose: expanding them (even interleaved `l , z `) would push the compiler image past the 4 MiB QbeGen.sessBuf. The principled general fix is to initialise such counts at runtime (a generated init loop), not in the static data; until then the latent 0-count bug remains for very large record arrays. See docs/summary_l3_selfhost_fix.md. *) TYPE ProcEnt = RECORD name : ARRAY [0..63] OF CHAR; END; VAR procs : ARRAY [0..3] OF ProcEnt; nProcs : CARDINAL; ExitCode: INTEGER; PROCEDURE CopyN (src: ARRAY OF CHAR; VAR dst: ARRAY OF CHAR); VAR i: CARDINAL; BEGIN i := 0; WHILE (i < 63) AND (src[i] # CHR(0)) DO dst[i] := src[i]; INC(i) END; dst[i] := CHR(0) END CopyN; PROCEDURE NoteProc (name: ARRAY OF CHAR); BEGIN CopyN(name, procs[nProcs].name); INC(nProcs) END NoteProc; BEGIN NoteProc("hello"); IF procs[0].name[0] = "h" THEN ExitCode := 0 ELSE ExitCode := 1 END END ArrRecFieldOpenArray.