Tag v3-fixpoint. Main suite 111/111.
V3, compiled by V3 itself, compiles the whole compiler source set to
a byte-identical gen_ssa/M2.ssa:
M2 (built by gm2 -fiso) compiles SymTab QbeGen M2S M2P M2(driver)
-> gen_ssa/M2.ssa (1,991,439 bytes)
M2self (built by V3 from that image) compiles the same set
-> gen_ssa/M2.ssa
cmp: *** IDENTICAL (FULL FIXPOINT) ***
So Stage 2 (V3 compiling itself) reproduces Stage 1's image exactly — the self-hosting fixpoint.
QbeGen.InitHeap, for a nested array (ARRAY … OF ARRAY …) on the
heap/stack, allocated each element sub-array with NewHeap but never
initialised its descriptor header. A local ARRAY [0..15] OF Name
therefore had sub-descriptors with garbage headers, and passing
names[i] to an ARRAY OF CHAR formal trapped in the scanner's
GetName. Fix: call InitHeap(eb, elem) on each sub-array.
Repro:
TYPE Name = ARRAY [0..63] OF CHAR;
PROCEDURE P;
VAR names: ARRAY [0..3] OF Name; i: CARDINAL;
PROCEDURE Set (VAR s: ARRAY OF CHAR); BEGIN s[0] := 'x' END Set;
BEGIN i := 0; Set(names[i]) END P;
From "sources compile and link" to the fixpoint, each step a real V3
runtime/ABI bug with a minimal repro: nested modules; inline record
array fields; the NUL-terminated string model; p^ as a VAR actual;
de-eagered NIL guards; off-by-one string scans; short-circuit AND/OR;
and now nested-array heap initialisation.
bootstrap/fixpoint.sh: automate Stage1 gm2 → Stage2 V3 → Stage3 V3
and cmp the images (the manual chain above already shows Stage2 ==
Stage1). Stage-aware CR flag: -m for gm2, no -m for V3.FileIO selection (stage 1 uses the host FileIO; stage 2+
the self-hosted runtime/syslib/FileIO).compiler/src/{QbeGen.mod,M2.lst}.