At least the Delphi 2010 compiler can be tricked to not generate wrong code.

At least the Delphi 2010 compiler can be tricked to not generate wrong code.

This program will crash in Delphi 2010 because the wrong finalization code causes the reference count of the wrapped interface to reach 0.

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  ITest = interface;

  Test = record
    //fDummy: Pointer; // <- uncomment this to cause correct finalization
    FTest: ITest;
    procedure Something;
  end;

  ITest = interface
    procedure Something;
    function AsRecord: Test;
  end;

  TTest = class(TInterfacedObject, ITest)
  public
    procedure Something;
    function AsRecord: Test;
  end;

procedure Test.Something;
begin
  FTest.Something;
end;

function TTest.AsRecord: Test;
begin
  Result.FTest := Self;
end;

procedure TTest.Something;
begin
end;

procedure Run(i: ITest);
begin
  i.AsRecord.Something;  
end;  // <- some wrong finalization code generated here

var
  t: ITest;
begin
  try
    t := TTest.Create;
    Run(t);
    Run(t);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

Comments

  1. Stefan Glienke This code works perfectly when compiled with Delphi XE3.

    ReplyDelete
  2. François Piette I know. It was a compiler bug in 2010 with the compiler generated temp record value for the function result.

    ReplyDelete
  3. Stefan Glienke If you knew it, you should have stated it.

    ReplyDelete
  4. Why do you think I wrote "this program will crash in Delphi 2010"?

    ReplyDelete

Post a Comment