The compiler generates incorrect code for shortstring
when using the function
function TTestObject<T>.Compare(const Left, Right: T): integer; inline;
It mangles the parameters.
The following sample program demonstrates the concept:
program ShortStringsAndConst;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
type
TStr100 = string[100];
TTestObject<T> = class
private
Bag1, Bag2: T;
procedure RandomBags;
procedure TestCompare;
function CompareFail(const Left, Right: T): integer; inline;
function CompareWin(const [ref] Left, Right: T): integer; inline;
end;
var
TestStr100: TTestObject<TStr100>;
procedure Test;
begin
TestStr100:= TTestObject<TStr100>.Create;
TestStr100.RandomBags;
TestStr100.TestCompare;
end;
{ TTestObject<T> }
procedure TTestObject<T>.RandomBags;
var
a: integer;
begin
PByteArray(@Bag1)^[0]:= SizeOf(T)- 1;
for a:= 1 to SizeOf(T)- 1 do begin
PByteArray(@Bag1)^[a]:= byte('a');
end;
Bag2:= Bag1;
end;
function TTestObject<T>.CompareFail(const Left, Right: T): integer;
var
L,R: shortstring;
begin
L:= PShortstring(@Left)^;
R:= PShortstring(@Right)^;
WriteLn(Format('Fail!! @Left = %p, @Right = %p, Left = %s, Right = %s',[@Left, @Right, L, R]));
end;
function TTestObject<T>.CompareWin(const [ref] Left, Right: T): integer;
var
L,R: shortstring;
begin
L:= PShortstring(@Left)^;
R:= PShortstring(@Right)^;
WriteLn(Format('Win: @Left = %p, @Right = %p, Left = %s, Right = %s',[@Left, @Right, L, R]));
end;
procedure TTestObject<T>.TestCompare;
begin
CompareFail(Bag1,Bag2);
WriteLn;
CompareWin(Bag1,Bag2);
ReadLn;
end;
begin
Test;
end.
Question
Is it an error on my part to assume I can get away with using normal const
in generic functions, or is this a compiler bug?
Bonus question
Besides Shortstring, are there other types which cause CompareFail
to generate non-working code?
Background
I don't feel a strong need to work with shortstring
, but I'm writing some generic library code and need to support all types.
Update This is a compiler bug which has been fixed in 10.1 Berlin.
Is it an error on my part to assume I can get away with using normal const in generic functions, or is this a compiler bug?
Assuming that what you say is true, then this is a compiler bug. You need to report the bug and block the use of short strings.