[fpc-devel] Type helper bug
Zeljko Avramovic
avra at writeme.com
Wed May 5 12:37:40 CEST 2021
In example bellow, both record field ID.PGN and type helper for that record field ID.PGN.PS point to the same memory location in a bitpacked record not aligned to a byte. ID.PGN can be modified correctly. ID.PGN.PS can not be modified correctly. If a field in a bitpacked record can work well (probably by masking and bit shifting), then helper should be able to do the same.
Could someone please take a look? Thanks!
Here is the bug report: https://bugs.freepascal.org/view.php?id=38678
---------------------------------------------------------------------
program TestTypeHelperBug;
{$mode delphi} {$H+}
{$modeswitch typehelpers}
type
T18bits = 0..(1 shl 18)-1;
TBitPackedRec = bitpacked record
SA: 0..(1 shl 7)-1;
PGN: T18bits;
PR: 0..7;
end;
T18bitsHelper = type helper for T18bits
private
function GetPS: byte;
procedure SetPS(const ANewPS: byte);
public
property PS: byte read GetPS write SetPS;
end;
function T18bitsHelper.GetPS: byte;
begin
Result := Self and $FF; // and %00 00000000 11111111 (PS is in lowest 8 bits)
end;
procedure T18bitsHelper.SetPS(const ANewPS: byte);
begin
Self := (Self and $3FF00) or ANewPS; // and %11 11111111 00000000
end;
var
PGN: T18bits;
ID: TBitPackedRec;
begin
PGN := 100;
WriteLn('1. PGN = ', PGN); // PGN is 100 as it should be
WriteLn('1. PGN.PS = ', PGN.PS); // PGN.PS is 100 as it should be
PGN.PS := 255;
WriteLn('2. PGN = ', PGN); // PGN is 255 as it should be
WriteLn('2. PGN.PS = ', PGN.PS); // PGN.PS is 255 as it should be
ID.SA := $55;
ID.PR := 3;
ID.PGN := 100;
WriteLn('1. ID.PGN = ', ID.PGN); // PGN is 100 as it should be
WriteLn('1. ID.PGN.PS = ', ID.PGN.PS); // PGN.PS is 100 as it should be
WriteLn('1. ID.SA = ', ID.SA); // PGN.SA is 85 as it should be
WriteLn('1. ID.PR = ', ID.PR); // PGN.PR is 3 as it should be
ID.PGN.PS := 255;
WriteLn('2. ID.PGN = ', ID.PGN); // PGN is 100 ( <<< WRONG!!! IT SHOULD BE 255)
WriteLn('2. ID.PGN.PS = ', ID.PGN.PS); // PGN.PS is 100 (WRONG!!! IT SHOULD BE 255)
WriteLn('2. ID.SA = ', ID.SA); // PGN.SA is 85 as it should be
WriteLn('2. ID.PR = ', ID.PR); // PGN.PR is 3 as it should be
end.
More information about the fpc-devel
mailing list