MODULE NestedArrayFieldBug; (* Repro: a RECORD field that is a nested ARRAY OF ARRAY OF CHAR, accessed as `arr[i].field[j][k]`, is miscompiled by V3 -> segfault (rc 139). Observed 2026-10-05. Expected exit 42; observed 139. Found while adding Lower's procedure-formal name table (a module-level ARRAY OF RECORD with a `pname : ARRAY [0..31] OF ARRAY [0..63] OF CHAR` field): the V3-built compiler crashed (SIGABRT) on every input. Flattening the field to `ARRAY [0..2047] OF CHAR` fixed that crash. STATUS (2026-10-05): - The *stride* half is FIXED (commit v3-fix-arrayrec-stride): QbeGen.ArrBodyItems now uses SymTab.TypeSize for record/class/set array elements, so an ARRAY OF record has correct element size and flat field access works (see tests/t_recarr.mod, exit 42). - This nested case is FIXED: ArrBodyItems now expands array-of-record elements per element (EmitRec) when the record (recursively) has a nested-array field, and ArrData emits the matching per-element sub-descriptors (EmitRecStatics). Plain record arrays (no nested array field) stay a compact zero blob, so AST.arena does not balloon. Regression test: tests/t_nestarr.mod (exit 42). Compare with docs/wip/local-array-bug.mod (local arrays) and the Stage-A array-of-record stride fix (QbeGen.ElemSize). *) VAR ExitCode : INTEGER; CONST MaxName = 63; MaxProc = 4; TYPE PE = RECORD name : ARRAY [0..MaxName] OF CHAR; npar : CARDINAL; pname : ARRAY [0..3] OF ARRAY [0..MaxName] OF CHAR; (* nested *) END; VAR procs : ARRAY [0..MaxProc-1] OF PE; nProcs : CARDINAL; PROCEDURE Reset; BEGIN nProcs := 0 END Reset; PROCEDURE NoteProc (name : ARRAY OF CHAR); VAR i : CARDINAL; BEGIN IF nProcs >= MaxProc THEN RETURN END; i := 0; WHILE (i < MaxName) AND (name[i] # CHR(0)) DO procs[nProcs].name[i] := name[i]; INC(i) END; procs[nProcs].name[i] := CHR(0); procs[nProcs].npar := 0; INC(nProcs) END NoteProc; PROCEDURE NoteParam (name : ARRAY OF CHAR); VAR j, i : CARDINAL; BEGIN IF nProcs = 0 THEN RETURN END; j := procs[nProcs-1].npar; i := 0; WHILE (i < MaxName) AND (name[i] # CHR(0)) DO procs[nProcs-1].pname[j][i] := name[i]; INC(i) END; procs[nProcs-1].pname[j][i] := CHR(0); procs[nProcs-1].npar := j + 1 END NoteParam; BEGIN Reset; NoteProc("Add"); NoteParam("a"); IF (nProcs = 1) AND (procs[0].pname[0][0] = "a") THEN ExitCode := 42 ELSE ExitCode := 1 END END NestedArrayFieldBug.