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.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to