HelperBug.pas (1,585 bytes)
program HelperBug;
{$modeswitch advancedrecords}
{$modeswitch typehelpers}
type
TTestInner = record
A: Integer;
B: array of Integer;
procedure SetBWithoutHelper(Value: Integer); inline;
end;
TTest = record
A: Integer;
B: array of Integer;
TestInner: TTestInner;
end;
TTestHelper = record helper for TTest
procedure SetBWithHelper(Value: Integer); inline;
end;
TTestInnerHelper = record helper for TTestInner
procedure SetBWithHelper(Value: Integer); inline; //inline is needed for error
end;
procedure TTestInner.SetBWithoutHelper(Value: Integer);
begin
B[0] := Value;
end;
procedure TTestInnerHelper.SetBWithHelper(Value: Integer);
begin
B[0] := Value;
end;
procedure TTestHelper.SetBWithHelper(Value: Integer);
begin
B[0] := Value;
end;
var
Test: TTest;
begin
Test.B := nil; //Otherwise compiler warns, despite setlength initializes everything to 0 according to documentation
//Setting lengths
setlength(Test.B, 1);
setlength(Test.TestInner.B, 1); //Note: Curiously compiler does NOT warn here about no initialization
//First tests all fine
Test.B[0] := 1;
Test.SetBWithHelper(1);
with Test do
SetBWithHelper(1);
//Still all fine here
Test.TestInner.B[0] := 1;
Test.TestInner.SetBWithHelper(1);
Test.TestInner.SetBWithoutHelper(1);
with Test.TestInner do
SetBWithoutHelper(1);
//Causes range check error or crashes without checks
with Test.TestInner do
SetBWithHelper(1);
end.