Skip to content

Compiler: Fatal: Internal error 2021010301 (with generics)

Summary

Compiling a generic procedure where the type has a count causes a fatal internal error, but not on the generic procedure.

System Information

  • Operating system: Linux, x86_64, OpenSuse Leap 15.6 (also on AlmaLinux 9.4)
  • Processor architecture: x86-64, 64-bit
  • Compiler version: trunk, 3.3.1, 3.3.1-16505-gfdae200281
  • Device: Desktop Personal Computer

Steps to reproduce

Given these three source files:

unit_a.pas

unit unit_a;

interface

type
  tLoopAll     = reference to procedure (const i: integer);
  tMemberSeqId = reference to procedure (const member: pointer; const seqId: integer);

procedure loop (const start: integer; const final_value: integer; const loopPr: tLoopAll);
//generic procedure loop<T> (const list: T; const doItem: tMemberSeqId);

implementation


procedure loop (const start: integer; const final_value: integer; const loopPr: tLoopAll);
  procedure forward_iterate (i: integer = 0);
    begin
      for i := start to final_value do loopPr(i);
    end;

  procedure reverse_iterate (i: integer = 0);
    begin
      for i := start downto final_value do loopPr(i);
    end;

  begin
    if final_value < start then reverse_iterate
    else
      forward_iterate;
  end;

generic procedure loop<T> (const list: T; const doItem: tMemberSeqId);
  begin
    loop(0, list.count - 1, procedure (const i: integer)
    begin
      doItem(list.items[i], i);
    end);
  end;

end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF;

unit_b.pas

unit unit_b;

interface

type
  tProc  = reference to procedure;
  tProcs = array of tProc;

procedure pick_all (const procs: tProcs);

implementation

uses unit_a;

procedure pick_all (const procs: tProcs);
  begin
    if length(procs) > 0 then loop(low(procs), high(procs), procedure (const i: integer)
      begin
        procs[i]();
      end);
  end;

end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF

appmain.pas

program appmain;

uses unit_b;

begin
end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF;

When compiling it the following occurs:

$ fpc -Mobjfpc -Sh -Fcutf8 -MadvancedRecords -MtypeHelpers -MfunctionReferences -ManonymousFunctions -MimplicitFunctionSpecialization -gh -gl -gp -gw3 -Xi -Sm -Sg -Os -Si appmain.pas
Free Pascal Compiler version 3.3.1 [2024/09/26] for x86_64
Copyright (c) 1993-2024 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling appmain.pas
Compiling unit_b.pas
Compiling unit_a.pas
unit_a.pas(19,5) Fatal: Internal error 2021010301
Fatal: Compilation aborted
Error: /home/dev/fpc_usr/lib/fpc/3.3.1/ppcx64 returned an error exitcode

( line 19 is in the pick_all function )

Example Project

See Steps to reproduce

What is the current bug behavior?

See Steps to reproduce, compiler gives a Fatal: Internal error 2021010301 error.

What is the expected (correct) behavior?

That the code compile with no errors. Something to note is if the generic procedure is commented out, the code compiles.

unit_a.pas

unit unit_a;

interface

type
  tLoopAll     = reference to procedure (const i: integer);
  tMemberSeqId = reference to procedure (const member: pointer; const seqId: integer);

procedure loop (const start: integer; const final_value: integer; const loopPr: tLoopAll);
//generic procedure loop<T> (const list: T; const doItem: tMemberSeqId);

implementation


procedure loop (const start: integer; const final_value: integer; const loopPr: tLoopAll);
  procedure forward_iterate (i: integer = 0);
    begin
      for i := start to final_value do loopPr(i);
    end;

  procedure reverse_iterate (i: integer = 0);
    begin
      for i := start downto final_value do loopPr(i);
    end;

  begin
    if final_value < start then reverse_iterate
    else
      forward_iterate;
  end;
{
generic procedure loop<T> (const list: T; const doItem: tMemberSeqId);
  begin
    loop(0, list.count - 1, procedure (const i: integer)
    begin
      doItem(list.items[i], i);
    end);
  end;
}
end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF;

Code compiles without error:

$ fpc -Mobjfpc -Sh -Fcutf8 -MadvancedRecords -MtypeHelpers -MfunctionReferences -ManonymousFunctions -MimplicitFunctionSpecialization -gh -gl -gp -gw3 -Xi -Sm -Sg -Os -Si appmain.pas
Free Pascal Compiler version 3.3.1 [2024/09/26] for x86_64
Copyright (c) 1993-2024 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling appmain.pas
Compiling unit_b.pas
Compiling unit_a.pas
Linking appmain
72 lines compiled, 0.1 sec, 174496 bytes code, 1152456 bytes data

Relevant logs and/or screenshots

See Steps to reproduce

Possible fixes

Not sure, I the code that I had to isolate this repro example from was building and running last year

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information