Recent

Author Topic: likely bug in FPC v3.0.4 64bit  (Read 1912 times)

440bx

  • Hero Member
  • *****
  • Posts: 3946
likely bug in FPC v3.0.4 64bit
« 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.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1058
Re: likely bug in FPC v3.0.4 64bit
« Reply #1 on: October 03, 2021, 02:02:24 pm »
Both cases are fixed in trunk now (this and the linked topic).

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: likely bug in FPC v3.0.4 64bit
« Reply #2 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.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: likely bug in FPC v3.0.4 64bit
« Reply #3 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 **

Thaddy

  • Hero Member
  • *****
  • Posts: 14210
  • Probably until I exterminate Putin.
Re: likely bug in FPC v3.0.4 64bit
« Reply #4 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....
Specialize a type, not a var.

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1058
Re: likely bug in FPC v3.0.4 64bit
« Reply #5 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}.

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: likely bug in FPC v3.0.4 64bit
« Reply #6 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