sonar-delphi
sonar-delphi copied to clipboard
Incorrect intrinsic return type for `System.Length` on dynamic arrays
Prerequisites
- [X] This bug is in SonarDelphi, not SonarQube or my Delphi code.
- [X] This bug has not already been reported.
SonarDelphi version
1.9.0
SonarQube version
No response
Issue description
In Delphi 12 the length of open array parameters was changed to be a NativeInt
(from Integer
).
#142 made a change to reflect this, however we didn't realise that this was a fix to bring open arrays in line with dynamic arrays.
Furthermore, the actual return type of the Length
intrinsic is platform dependent, and not just in the way that NativeInt
is.
Here's a Delphi program that can be used to inspect the return type of Length
. For good measure, I included const arrays.
program LengthIntrinsicType;
{$APPTYPE console}
uses System.TypInfo;
type
TypeInformation = record
class function name<T> (const value : T) : string; static;
end;
class function TypeInformation.name<T> (const value : T) : string;
begin
Result := GetTypeName(TypeInfo(T));
end;
procedure Test(openarr: array of byte);
const
constarr: array[0..0] of byte = (0);
var
dynarr: array of byte;
begin
WriteLn('Dynamic array length type: ', TypeInformation.Name(Length(dynarr)));
WriteLn('Open array length type: ', TypeInformation.name(Length(openarr)));
WriteLn('Const array length type: ', TypeInformation.name(Length(constarr)));
WriteLn('NativeInt TypeInfo: ', NativeInt(TypeInfo(NativeInt)));
WriteLn('Int64 TypeInfo: ', NativeInt(TypeInfo(Int64)));
WriteLn('Integer TypeInfo: ', NativeInt(TypeInfo(Integer)));
end;
begin
Test([0]);
readln;
end.
My findings are
Delphi Version | Platform | Type(Length(OpenArray)) | Type(Length(DynArray)) | Type(Length(ConstArray)) |
---|---|---|---|---|
11 | 32-bit | Integer | Integer | Integer |
11 | 64-bit | Integer | NativeInt | Integer |
12 | 32-bit | NativeInt | NativeInt | Integer |
12 | 64-bit | NativeInt | NativeInt | Integer |
Note that on Delphi 12 NativeInt is a weak alias, so the runtime type information cannot distinguish the alias from the aliased type - this is why my test program prints the TypeInfo
pointer. To make the results easier to understand, I have substituted NativeInt
for some of the Delphi 12 results.
My conclusions are
- In Delphi 12+ open and dynamic arrays both always have a length of type
NativeInt
(which is a weak alias) - In Delphi 11-
- Only dynamic arrays have a length of type
NativeInt
on 64-bit butInteger
on 32-bit (notNativeInt
strongly aliased toInteger
) - Open arrays always have a length of type
Integer
- Only dynamic arrays have a length of type
- Const arrays always have a length of
Integer
The current modelling doesn't match this https://github.com/integrated-application-development/sonar-delphi/blob/51412489dc8158268ae5e9d7681e92acbe2a6269/delphi-frontend/src/main/java/au/com/integradev/delphi/type/intrinsic/IntrinsicReturnType.java#L115-L125
Steps to reproduce
n/a
Minimal Delphi code exhibiting the issue
No response