Lazarus

Free Pascal => General => Topic started by: 440bx on September 18, 2021, 05:16:22 am

Title: likely bug in FPC v3.0.4 64bit
Post by: 440bx on September 18, 2021, 05:16:22 am
Hello,

In 64bit, getting the sizeof a bitpacked record that is made of bits does not return the correct value.

In the sample program below, when compiled for 32bit, the result is 4 bytes as it should be but, when compiled for 64bit the result is 1 instead of 8.

Code: Pascal  [Select][+][-]
  1. {$APPTYPE       CONSOLE}
  2.  
  3. {$TYPEDADDRESS  ON}
  4.  
  5. {$LONGSTRINGS   OFF}
  6.  
  7. { --------------------------------------------------------------------------- }
  8.  
  9. {$DEFINE ENABLE_BIT_FIELDS}
  10. {$DEFINE PROBLEMATIC_DEFINITION}
  11.  
  12. program _TRTL_BALANCED_NODE2;
  13.   { program to verify the offsets in the TRTL_BALANCED_NODE structure         }
  14.  
  15.  
  16. type
  17.   { bit types for bitfields                                                  }
  18.  
  19.    _1bit     = 0 ..                $1;
  20.    _2bits    = 0 ..                $3;
  21.    _3bits    = 0 ..                $7;
  22.    _4bits    = 0 ..                $F;
  23.    _5bits    = 0 ..               $1F;
  24.    _6bits    = 0 ..               $3F;
  25.    _7bits    = 0 ..               $7F;
  26.    _8bits    = 0 ..               $FF;    { byte                              }
  27.    _9bits    = 0 ..              $1FF;
  28.  
  29.   _10bits    = 0 ..              $3FF;
  30.   _11bits    = 0 ..              $7FF;
  31.   _12bits    = 0 ..              $FFF;
  32.   _13bits    = 0 ..             $1FFF;
  33.   _14bits    = 0 ..             $3FFF;
  34.   _15bits    = 0 ..             $7FFF;
  35.   _16bits    = 0 ..             $FFFF;    { word                              }
  36.   _17bits    = 0 ..            $1FFFF;
  37.   _18bits    = 0 ..            $3FFFF;
  38.   _19bits    = 0 ..            $7FFFF;
  39.  
  40.   _20bits    = 0 ..            $FFFFF;
  41.   _21bits    = 0 ..           $1FFFFF;
  42.   _22bits    = 0 ..           $3FFFFF;
  43.   _23bits    = 0 ..           $7FFFFF;
  44.   _24bits    = 0 ..           $FFFFFF;
  45.   _25bits    = 0 ..          $1FFFFFF;
  46.   _26bits    = 0 ..          $3FFFFFF;
  47.   _27bits    = 0 ..          $7FFFFFF;
  48.   _28bits    = 0 ..          $FFFFFFF;
  49.   _29bits    = 0 ..         $1FFFFFFF;
  50.  
  51.   _30bits    = 0 ..         $3FFFFFFF;
  52.   _31bits    = 0 ..         $7FFFFFFF;
  53.  
  54.   _32bits    = 0 ..         $FFFFFFFF;    { DWORD                             }
  55.  
  56.   _33bits    = 0 ..        $1FFFFFFFF;
  57.   _34bits    = 0 ..        $3FFFFFFFF;
  58.   _35bits    = 0 ..        $7FFFFFFFF;
  59.   _36bits    = 0 ..        $FFFFFFFFF;
  60.   _37bits    = 0 ..       $1FFFFFFFFF;
  61.   _38bits    = 0 ..       $3FFFFFFFFF;
  62.   _39bits    = 0 ..       $7FFFFFFFFF;
  63.  
  64.   _40bits    = 0 ..       $FFFFFFFFFF;
  65.   _41bits    = 0 ..      $1FFFFFFFFFF;
  66.   _42bits    = 0 ..      $3FFFFFFFFFF;
  67.   _43bits    = 0 ..      $7FFFFFFFFFF;
  68.   _44bits    = 0 ..      $FFFFFFFFFFF;
  69.   _45bits    = 0 ..     $1FFFFFFFFFFF;
  70.   _46bits    = 0 ..     $3FFFFFFFFFFF;
  71.   _47bits    = 0 ..     $7FFFFFFFFFFF;
  72.   _48bits    = 0 ..     $FFFFFFFFFFFF;
  73.   _49bits    = 0 ..    $1FFFFFFFFFFFF;
  74.  
  75.   _50bits    = 0 ..    $3FFFFFFFFFFFF;
  76.   _51bits    = 0 ..    $7FFFFFFFFFFFF;
  77.   _52bits    = 0 ..    $FFFFFFFFFFFFF;
  78.   _53bits    = 0 ..   $1FFFFFFFFFFFFF;
  79.   _54bits    = 0 ..   $3FFFFFFFFFFFFF;
  80.   _55bits    = 0 ..   $7FFFFFFFFFFFFF;
  81.   _56bits    = 0 ..   $FFFFFFFFFFFFFF;
  82.   _57bits    = 0 ..  $1FFFFFFFFFFFFFF;
  83.   _58bits    = 0 ..  $3FFFFFFFFFFFFFF;
  84.   _59bits    = 0 ..  $7FFFFFFFFFFFFFF;
  85.  
  86.   _60bits    = 0 ..  $FFFFFFFFFFFFFFF;
  87.   _61bits    = 0 .. $1FFFFFFFFFFFFFFF;
  88.   _62bits    = 0 .. $3FFFFFFFFFFFFFFF;
  89.   _63bits    = 0 .. $7FFFFFFFFFFFFFFF;
  90.  
  91. type
  92.   PRTL_BALANCED_NODE = ^TRTL_BALANCED_NODE;
  93.   TRTL_BALANCED_NODE = packed record
  94.     Node                 : record
  95.       case integer of
  96.         1 : (
  97.              Children        : array[0..1] of PRTL_BALANCED_NODE;
  98.             );
  99.  
  100.         2 : (
  101.              Left            : PRTL_BALANCED_NODE;
  102.              Right           : PRTL_BALANCED_NODE;
  103.             );
  104.     end;
  105.  
  106.     Value                : {$ifdef FPC} bitpacked {$endif} record
  107.       case integer of
  108.         1 : (
  109.              ParentValue     : ptruint;
  110.             );
  111.  
  112.  
  113.         { ------------------------------------------------------------------- }
  114.         { something in these bit fields is not right                          }
  115.  
  116.         {$ifdef ENABLE_BIT_FIELDS}
  117.         {$ifdef PROBLEMATIC_DEFINITION}
  118.         {$ifdef FPC}
  119.         2 : (
  120.              TestSizeA       : bitpacked record
  121.                Red               :  _1bit;
  122.  
  123.                {$ifdef WIN32}                    { no problem in 32bits       }
  124.                  FillerRed       : _31bits;
  125.                {$endif}
  126.  
  127.                {$ifdef WIN64}
  128.                  { likely due to a compiler bug, specifying _63bits causes the}
  129.                  { sizeof of the record to be one byte too large.             }
  130.  
  131.                  FillerRed       : _62bits;     { 62 + 1 works, 63 doesn't    }
  132.                  Filler          :  _1bit;
  133.              {$endif}
  134.              end;
  135.             );
  136.         {$endif}
  137.         {$endif}
  138.  
  139.  
  140.         {$ifdef FPC}
  141.         3 : (
  142.              TestSizeB       : bitpacked record
  143.  
  144.                Balance           :  _2bits;
  145.  
  146.                {$ifdef WIN32}                  { no problem here              }
  147.                  FillerBalance   : _30bits;
  148.                {$endif}
  149.  
  150.                {$ifdef WIN64}                  { no problem here either       }
  151.                  FillerBalance   : _62bits;
  152.                {$endif}
  153.              end;
  154.             );
  155.         {$endif}
  156.         {$endif}
  157.     end;
  158.   end;
  159.  
  160.  
  161. var
  162.   V1 : record
  163.     F1 : TRTL_BALANCED_NODE;
  164.     F2 : TRTL_BALANCED_NODE;
  165.   end;
  166.  
  167.   SizeA, SizeB : ptruint;
  168.  
  169.  
  170. begin
  171.   writeln;
  172.   writeln;
  173.  
  174.   writeln('  sizeof(TRTL_BALANCED_NODE) : ', sizeof(TRTL_BALANCED_NODE));
  175.   writeln('  sizeof(V1)                 : ', sizeof(V1));
  176.  
  177.   writeln;
  178.   writeln;
  179.  
  180.   SizeA   := sizeof(TRTL_BALANCED_NODE.Value.TestSizeA);
  181.   write  ('  sizeof(TRTL_BALANCED_NODE.Value.TestSizeA) : ', SizeA);
  182.   if SizeA <> sizeof(ptruint) then writeln('  ** INCORRECT ** ') else writeln;
  183.  
  184.  
  185.   SizeB   := sizeof(TRTL_BALANCED_NODE.Value.TestSizeB);
  186.   write  ('  sizeof(TRTL_BALANCED_NODE.Value.TestSizeB) : ',SizeB);
  187.   if SizeB <> sizeof(ptruint) then writeln('  ** INCORRECT ** ') else writeln;
  188.  
  189.  
  190.   writeln;
  191.   writeln;
  192.   writeln('press ENTER/RETURN to end this program');
  193.   readln;
  194. end.
  195.  

NOTE: this problem is related to the one shown in
https://forum.lazarus.freepascal.org/index.php/topic,56339.msg418608/topicseen.html#new
but, it's a different problem.

NOTE: I do not know if this problem occurs in later versions of FPC.

Comments welcome.
Title: Re: likely bug in FPC v3.0.4 64bit
Post by: Jonas Maebe on October 03, 2021, 02:02:24 pm
Both cases are fixed in trunk now (this and the linked topic).
Title: Re: likely bug in FPC v3.0.4 64bit
Post by: 440bx on October 03, 2021, 08:23:47 pm
Both cases are fixed in trunk now (this and the linked topic).
Thank you for that.  Bug fixes are always welcome.
Title: Re: likely bug in FPC v3.0.4 64bit
Post by: bytebites on October 06, 2021, 09:04:50 am
Trunk-version outputs now.
Quote
  sizeof(TRTL_BALANCED_NODE) : 24
  sizeof(V1)                 : 48


  sizeof(TRTL_BALANCED_NODE.Value.TestSizeA) : 1  ** INCORRECT **
  sizeof(TRTL_BALANCED_NODE.Value.TestSizeB) : 1  ** INCORRECT **
Title: Re: likely bug in FPC v3.0.4 64bit
Post by: Thaddy on October 06, 2021, 12:23:10 pm
Trunk-version outputs now.
Quote
  sizeof(TRTL_BALANCED_NODE) : 24
  sizeof(V1)                 : 48


  sizeof(TRTL_BALANCED_NODE.Value.TestSizeA) : 1  ** INCORRECT **
  sizeof(TRTL_BALANCED_NODE.Value.TestSizeB) : 1  ** INCORRECT **

Code proof plz....
Title: Re: likely bug in FPC v3.0.4 64bit
Post by: Jonas Maebe on October 06, 2021, 12:28:12 pm
Trunk-version outputs now.
Quote
  sizeof(TRTL_BALANCED_NODE) : 24
  sizeof(V1)                 : 48


  sizeof(TRTL_BALANCED_NODE.Value.TestSizeA) : 1  ** INCORRECT **
  sizeof(TRTL_BALANCED_NODE.Value.TestSizeB) : 1  ** INCORRECT **
On which platform did you test? Note that the posted code uses {$ifdef win64}, so if you test on another OS then make sure to replace that with {$ifdef cpu64}.
Title: Re: likely bug in FPC v3.0.4 64bit
Post by: bytebites on October 06, 2021, 02:19:18 pm
After modification result is:  :)
Quote
  sizeof(TRTL_BALANCED_NODE) : 24
  sizeof(V1)                 : 48


  sizeof(TRTL_BALANCED_NODE.Value.TestSizeA) : 8
  sizeof(TRTL_BALANCED_NODE.Value.TestSizeB) : 8
TinyPortal © 2005-2018