[Rtti] TValue.From<TMyManagedRecord> leads to segfault

Summary

System Information

  • Operating system: Linux
  • Processor architecture: x86-64
  • Compiler version: trunk

This test failed with segfault because TValue.Make don't add refs to managed fields in records. Same for static array of managed types

program tw41013;
{$mode DELPHI}
uses
  Rtti
  ;

type
  TRec = record
    Num: IntPtr;
    Intf: IUnknown;
  end;
  TArrayOfRec = array[0..0] of TRec;

  TRec2 = record
    Num: IntPtr;
    Num2: IntPtr;
  end;

  TTestIntfObject = class(TInterfacedObject)

  end;

function GetValue: TValue;
var
  R: TRec;
begin
  R.Intf := TTestIntfObject.Create;
  Result := TValue.From<TRec>(R);
end;

function GetValue2: TValue;
var
  Arr: TArrayOfRec;
begin
  Arr[0].Intf := TTestIntfObject.Create;
  Result := TValue.From<TArrayOfRec>(Arr);
end;

var
  P: Pointer;
  R: TRec;
  Arr: TArrayOfRec;
  V: TValue;
begin
  V := GetValue();
  P := AllocMem(64);
  R := V.AsType<TRec>;
  if (R.Intf as TTestIntfObject).RefCount < 2 then
  begin // should be >= 2. One ref in in V, and another one is in R
    WriteLn('RefCount < 2 ???');
    Halt(1);
  end;
  FreeMem(P);

  V := GetValue2();
  P := AllocMem(64);
  Arr := V.AsType<TArrayOfRec>;
  if (Arr[0].Intf as TTestIntfObject).RefCount < 2 then
  begin
    WriteLn('RefCount < 2 ???');
    Halt(1);
  end;
  FreeMem(P);
end.
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information