4
votes

I wonder if I have found an Embarcadero compiler bug ...

The problem looks like it is related to generics.

Here is my source code

unit u_DateCount;

interface

uses
  SysUtils,
  u_JavaScriptable
  ;

type
  TDateCount = class (TJavaScriptable)
    strict private
    public
      NoOfSamples : Integer;
      TheDate : TDate;
      function ToString():String; override;
  end;

implementation

function TDateCount.ToString():String;
var
    myYear, myMonth, myDay : Word;
begin
    DecodeDate(TheDate, myYear, myMonth, myDay);
    Result := Format('[new Date(%d, %d ,0), %d]', [myYear, myMonth, NoOfSamples]);
end;

end.

unit u_Javascriptable;

interface

type
  TJavaScriptable = class
    strict private
    public
      function ToString:String; override;
  end;

implementation

function TJavaScriptable.ToString:String;
begin
    Result := '';
end;

end.

unit u_LineChart;

interface

uses
  System.IOUtils,
  SysUtils,
  System.Generics.Collections,
  u_JavaScriptable
  ;

type
  TLineChart<RecordType : TJavaScriptable> = class
    strict private
      Template : String;
      function ConvertRecordsToString():String;
    public
      Records : TList<RecordType>;
      function ToString():String;
      constructor Create(templatePath : String);
      destructor Destroy(); override;
  end;

implementation

function TLineChart<RecordType>.ConvertRecordsToString():String;
var
    I: Integer;
begin
    //Open brackets
    Result := '[ ';

    //The first record
    if Records.Count > 0 then
    begin
        Result := Result + Records[0].ToString();
    end;

    //Loop over records
    for I := 1 to Records.Count - 1 do
    begin
        Result := Result + ', ' + Records[I].ToString();
    end;

    //Close bracket
    Result := Result + ' ]';
end;

function TLineChart<RecordType>.ToString():String;
begin
    Result := Format(Template, [ConvertRecordsToString()]);
end;

constructor TLineChart<RecordType>.Create(templatePath : String);
begin
    inherited Create();
    Template := TFile.ReadAllText(templatePath);
    Records := TList<RecordType>.Create();
end;

destructor TLineChart<RecordType>.Destroy();
var
    I: Integer;
begin
    if Assigned(Records) then
    begin
        for I := 0 to Records.Count - 1 do
        begin
            Records[I].Destroy();
        end;
        Records.Clear();
        Records.Destroy();
        Records := nil;
    end;

    inherited;
end;

end.

And finally the main program

program Project4;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  u_Javascriptable in 'u_Javascriptable.pas',
  u_LineChart in 'u_LineChart.pas',
  u_DateCount in 'u_DateCount.pas';

var
   lineChart : TLineChart<TDateCount>;

begin

  lineChart := TLineChart<TDateCount>.Create('linechart.html');
  try


  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

The error message I get when I try to compile this is

[dcc32 Fatal Error] Project4.dpr(30): F2084 Internal Error: AV097530AC-R00000014-0

Usually when I see an error message similar to this, I can fix it by closing the embarcadero IDE and restarting it. However this did not seem to work this time.

3
I usually fix this error by cleaning and rebuilding my project.Javid
Thanks, just tried that. Its made no difference.sav
Try cleaning your project files (another option along with compile and build) which deletes all your compiled files, and then close/re-open the IDE, and rebuildJerry Dodge
Yup, tried that. I've even created a small project which reproduces the bug. Still no luck.sav
I have just compiled the program successfully using XE3. This must be an XE4 bug.sav

3 Answers

10
votes

The problem is in the implementation of TLineChart<RecordType>.Destroy().

Change Records[I].Destroy(); to Records[I].Free(); and it works. Or you just do it correct and use TObjectList<RecordType>.Create; in the constructor which takes care of destroying all elements in it when destroying the list.

Never call Destroy directly. Use Free. While it should not result in a compiler error it is wrong anyway.

4
votes

If the compiler reports an "internal error," that's always a compiler bug. You should open a ticket in QC for this. Hopefully they can get it fixed for XE5.

1
votes

Since this works in XE3 but not XE4, I'm going to presume this is an XE4 bug. Until this is fixed, the solution is to use a different version of the compiler such as XE3.