← board

A second specialization of a generic that has a nested type SEGFAULTS at runtime

Repro

type
  generic TD<K, V> = class
  public type TPair = record aa: K; bb: V; end;
  private FA: array of TPair;
  public procedure Put(const a: K; const b: V);
        function KeyAt(i: LongInt): K; function Count: LongInt;
  end;
type
  TSI = specialize TD<String, LongInt>;
  TII = specialize TD<LongInt, LongInt>;   { the SECOND one }
var a: TSI; b: TII;
begin
  a := TSI.Create; a.Put('one', 1); WriteLn(a.Count, ' ', a.KeyAt(0));  { prints "1 one" }
  b := TII.Create; b.Put(10, 20);   WriteLn(b.Count, ' ', b.KeyAt(0));  { SIGSEGV }
end.

It compiles clean and the first specialization runs correctly. The second segfaults — exit 139, after the first line has printed. fpc -Mobjfpc prints 1 one / 1 10.

Boundary

Why it matters

A compile-clean SIGSEGV is the worst failure shape here — no diagnostic, and it appears only when a second specialization is added, so it will look like the caller's fault. Generics.Collections specializes the same templates many times over, so rung 6 will hit this immediately after the shared-nested-name defect above, and the two should probably be investigated together: both are about a nested type's identity not being per-specialization.

Where to look

Likely the nested type is registered once and shared across specializations, so the second specialization's instance reads the first's layout (element size, managed-field descriptor). A wrong TPair size for array of TPair would give exactly this: correct first instance, wild pointer on the second. Confirm with PXXDBG=a.ir on Put for both specializations and compare the element size and field offsets.

Gate

Track P: make compiler/pascal26 (self-host fixedpoint) + the repro running and matching fpc -O2, plus tools/run_fgl_corpus.sh still 7/7. Add the repro as a test with an .expected.

Log