Recent

Author Topic: Likely bug in bit field size computation  (Read 1425 times)

440bx

  • Hero Member
  • *****
  • Posts: 6065
Likely bug in bit field size computation
« on: December 22, 2025, 06:52:09 am »
Hello,

When compiling for 32 bit, there are cases when FPC v3.2.2 incorrectly calculates the total size of bitfields.

The code below is attached to this post along with 32 and 64 bit project files to make testing simple:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. program BitFieldsSize;
  4.  
  5. type
  6.    _1bit     = 0 ..                $1;
  7.    _2bits    = 0 ..                $3;
  8.    _3bits    = 0 ..                $7;
  9.    _4bits    = 0 ..                $F;
  10.    _5bits    = 0 ..               $1F;
  11.    _6bits    = 0 ..               $3F;
  12.    _7bits    = 0 ..               $7F;
  13.    _8bits    = 0 ..               $FF;    { byte                              }
  14.    _9bits    = 0 ..              $1FF;
  15.  
  16.   _10bits    = 0 ..              $3FF;
  17.   _11bits    = 0 ..              $7FF;
  18.   _12bits    = 0 ..              $FFF;
  19.   _13bits    = 0 ..             $1FFF;
  20.   _14bits    = 0 ..             $3FFF;
  21.   _15bits    = 0 ..             $7FFF;
  22.   _16bits    = 0 ..             $FFFF;    { word                              }
  23.   _17bits    = 0 ..            $1FFFF;
  24.   _18bits    = 0 ..            $3FFFF;
  25.   _19bits    = 0 ..            $7FFFF;
  26.  
  27.   _20bits    = 0 ..            $FFFFF;
  28.   _21bits    = 0 ..           $1FFFFF;
  29.   _22bits    = 0 ..           $3FFFFF;
  30.   _23bits    = 0 ..           $7FFFFF;
  31.   _24bits    = 0 ..           $FFFFFF;
  32.   _25bits    = 0 ..          $1FFFFFF;
  33.   _26bits    = 0 ..          $3FFFFFF;
  34.   _27bits    = 0 ..          $7FFFFFF;
  35.   _28bits    = 0 ..          $FFFFFFF;
  36.   _29bits    = 0 ..         $1FFFFFFF;
  37.  
  38.   _30bits    = 0 ..         $3FFFFFFF;
  39.   _31bits    = 0 ..         $7FFFFFFF;
  40.   _32bits    = 0 ..         $FFFFFFFF;    { DWORD                             }
  41.  
  42.   _33bits    = 0 ..        $1FFFFFFFF;
  43.   _34bits    = 0 ..        $3FFFFFFFF;
  44.   _35bits    = 0 ..        $7FFFFFFFF;
  45.   _36bits    = 0 ..        $FFFFFFFFF;
  46.   _37bits    = 0 ..       $1FFFFFFFFF;
  47.   _38bits    = 0 ..       $3FFFFFFFFF;
  48.   _39bits    = 0 ..       $7FFFFFFFFF;
  49.  
  50.   _40bits    = 0 ..       $FFFFFFFFFF;
  51.   _41bits    = 0 ..      $1FFFFFFFFFF;
  52.   _42bits    = 0 ..      $3FFFFFFFFFF;
  53.   _43bits    = 0 ..      $7FFFFFFFFFF;
  54.   _44bits    = 0 ..      $FFFFFFFFFFF;
  55.   _45bits    = 0 ..     $1FFFFFFFFFFF;
  56.   _46bits    = 0 ..     $3FFFFFFFFFFF;
  57.   _47bits    = 0 ..     $7FFFFFFFFFFF;
  58.   _48bits    = 0 ..     $FFFFFFFFFFFF;
  59.   _49bits    = 0 ..    $1FFFFFFFFFFFF;
  60.  
  61.   _50bits    = 0 ..    $3FFFFFFFFFFFF;
  62.   _51bits    = 0 ..    $7FFFFFFFFFFFF;
  63.   _52bits    = 0 ..    $FFFFFFFFFFFFF;
  64.   _53bits    = 0 ..   $1FFFFFFFFFFFFF;
  65.   _54bits    = 0 ..   $3FFFFFFFFFFFFF;
  66.   _55bits    = 0 ..   $7FFFFFFFFFFFFF;
  67.   _56bits    = 0 ..   $FFFFFFFFFFFFFF;
  68.   _57bits    = 0 ..  $1FFFFFFFFFFFFFF;
  69.   _58bits    = 0 ..  $3FFFFFFFFFFFFFF;
  70.   _59bits    = 0 ..  $7FFFFFFFFFFFFFF;
  71.  
  72.   _60bits    = 0 ..  $FFFFFFFFFFFFFFF;
  73.   _61bits    = 0 .. $1FFFFFFFFFFFFFFF;
  74.   _62bits    = 0 .. $3FFFFFFFFFFFFFFF;
  75.   _63bits    = 0 .. $7FFFFFFFFFFFFFFF;
  76.  
  77.  
  78. const
  79.   QWORD_DEC_MAX  = 18446744073709551615;
  80.  
  81.   QWORD_HEX_MAX  = qword($FFFFFFFFFFFFFFFF);  // must typecast, otherwise error
  82.  
  83. type
  84.   _64bitsDec     = 0..QWORD_DEC_MAX;
  85.  
  86. type
  87.   _64bitsHex     = 0..QWORD_HEX_MAX;
  88.  
  89.  
  90. type
  91.   { _SYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION                                   }
  92.  
  93.    { $f3  243 }  { SystemTrustedAppsRuntimeInformation                        }
  94.  
  95.   PSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION = ^TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION;
  96.   TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION = record
  97.     union                                     : bitpacked record
  98.       case integer of
  99.         1 : (
  100.              Flags                                : qword;
  101.             );
  102.         2 : (
  103.              Supported                            :  _2bits;
  104.              Spare                                : _62bits;
  105.             );
  106.     end;
  107.  
  108.     { removed this field to simplify                                          }
  109.   end;
  110.  
  111.   {$ifdef WIN32}
  112.     { when compiling for 32 bit the following condition evaluates to FALSE    }
  113.     { which is incorrect.                                                     }
  114.  
  115.     {$if sizeof(TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION) <> $8}
  116.       {$FATAL sizeof TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION does not equal $8}
  117.     {$endif}
  118.   {$endif}
  119.  
  120.   {$ifdef WIN64}
  121.     {$if sizeof(TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION) <> $8}
  122.       {$FATAL sizeof TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION does not equal $8}
  123.     {$endif}
  124.   {$endif}
  125.  
  126.  
  127.  
  128. begin
  129.   writeln;
  130.   writeln(QWORD_DEC_MAX);
  131.   writeln(QWORD_HEX_MAX);
  132.   writeln;
  133.  
  134.   if sizeof(pointer) = 4 then writeln('32 bit size') else writeln('64 bit size');
  135.  
  136.   writeln;
  137.   writeln('sizeof TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION: ',
  138.            sizeof(TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION));
  139.  
  140.   readln;
  141. end.  
  142.  
When compiling the above code for 32 bit, the compiler complains that the size of the record does not equal 8 when it is 8, fact which can be verified by compiling for 64 bit (in this case the record size is bitness independent.)

It would be nice to know if the upcoming v3.2,4 exhibits the same problem.

Comments welcome.


ETA:

There is also a problem calculating bit field sizes in 64 bits.  To see the problem change "Supported  : _1bit;" and "Spare : _63bits" and the program will no longer compile in 64 bit.  (IOW, move 1 bit from the current "Supported" value to the "Spare" field value.  With that change the program will no longer compile in 64 bit (and, it definitely should.)

 
« Last Edit: December 22, 2025, 07:24:10 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

paweld

  • Hero Member
  • *****
  • Posts: 1568
Re: Likely bug in bit field size computation
« Reply #1 on: December 22, 2025, 07:59:25 am »
For 32-bit, it does not compile on either 3.2.3 (fixes) or 3.3.1 (trunk).
After changing to 1/63, it does not compile for 64-bit only in 3.2.3 (fixes), but it is OK in 3.3.1 (trunk).
Best regards / Pozdrawiam
paweld

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 369
  • I use FPC [main] 💪🐯💪
Re: Likely bug in bit field size computation
« Reply #2 on: December 22, 2025, 08:25:53 am »
FPC [main]
Windows

x64:
Code: Pascal  [Select][+][-]
  1. 18446744073709551615
  2. 18446744073709551615
  3.  
  4. 64 bit size
  5.  
  6. sizeof TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION: 8

x32:
Code: Pascal  [Select][+][-]
  1. BitFieldsSize.lpr(116,8) Error: User defined: sizeof TSYSTEM_TRUSTEDAPPS_RUNTIME_INFORMATION does not equal $8
  2.  
I may seem rude - please don't take it personally

440bx

  • Hero Member
  • *****
  • Posts: 6065
Re: Likely bug in bit field size computation
« Reply #3 on: December 22, 2025, 08:38:14 am »
In the meantime, I've been doing some additional testing.

It seems that part of the problem is when the total number of bits adds up to 64.  if they add up to less than 64 then it seems the compiler's behavior is ok (I say "seems" because I couldn't claim the testing I've done is extensive.)

One particularly insidious problem I found in 64 bit is that if a pointer field is defined where the comment  "{ removed this field to simplify }" currently is, then the compilation succeeds but the offset to the field is incorrect (it's off by 4 bytes.)

I wonder what v3.2.4RC1 does ... if someone has it installed and cares to test, I'd appreciate that.


« Last Edit: December 22, 2025, 08:40:43 am by 440bx »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 369
  • I use FPC [main] 💪🐯💪
Re: Likely bug in bit field size computation
« Reply #4 on: December 22, 2025, 09:12:57 am »
Interesting! Run this code first under x64, then under x32
Amazing! 😁

Code: Pascal  [Select][+][-]
  1. program BitFieldsSize;
  2.  
  3. type
  4.   TRec64_v0 = bitpacked record
  5.     Half1: 0..UInt64(1 shl 32)-1;
  6.     Half2: 0..UInt64(1 shl 32)-1;
  7.   end;
  8.   TRec64_v1 = bitpacked record
  9.     Half1: 0..UInt64(1 shl  1)-1;
  10.     Half2: 0..UInt64(1 shl 63)-1;
  11.   end;
  12.   TRec64_v2 = bitpacked record
  13.     Half1: 0..UInt64(1 shl 16)-1;
  14.     Half2: 0..UInt64(1 shl 48)-1;
  15.   end;
  16.  
  17. begin
  18.   writeln('sizeof TRec64_v0: ', sizeof(TRec64_v0));
  19.   writeln('sizeof TRec64_v1: ', sizeof(TRec64_v1));
  20.   writeln('sizeof TRec64_v2: ', sizeof(TRec64_v2));
  21.  
  22.   readln;
  23. end.
I may seem rude - please don't take it personally

440bx

  • Hero Member
  • *****
  • Posts: 6065
Re: Likely bug in bit field size computation
« Reply #5 on: December 22, 2025, 09:21:51 am »
Yes, interesting indeed.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

ASerge

  • Hero Member
  • *****
  • Posts: 2475
Re: Likely bug in bit field size computation
« Reply #6 on: December 22, 2025, 03:20:51 pm »
Yes, interesting indeed.
Especially if change 63 to 62. On x64:
Quote
sizeof TRec64_v0: 8
sizeof TRec64_v1: 0
sizeof TRec64_v2: 8

paweld

  • Hero Member
  • *****
  • Posts: 1568
Re: Likely bug in bit field size computation
« Reply #7 on: December 22, 2025, 05:55:25 pm »

I wonder what v3.2.4RC1 does ... if someone has it installed and cares to test, I'd appreciate that.
Version 3.2.4rc1 behaves exactly the same as 3.2-fixes.
Best regards / Pozdrawiam
paweld

440bx

  • Hero Member
  • *****
  • Posts: 6065
Re: Likely bug in bit field size computation
« Reply #8 on: December 22, 2025, 07:10:16 pm »
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018