Incorrect record size computation when bitfields are present
Summary
When a record includes bitfields, there are cases when the compiler will calculate the record size incorrectly.
System Information
In general, the bug seems to occur when the total size of the bitfields adds up to 64. However, there may be other cases.
-
Operating system: Windows and possibly other O/Ss.
-
Processor architecture: x86-64
-
Compiler version: Multiple versions including v3.2.2 and v3.2.4RC1
-
Device: Computer
Steps to reproduce
declare a record which has at least one set of bitfields that add up to 64.
Example Project
type
TRec64_v0 = bitpacked record
Half1: 0..UInt64(1 shl 32)-1;
Half2: 0..UInt64(1 shl 32)-1;
end;
TRec64_v1 = bitpacked record
Half1: 0..UInt64(1 shl 1)-1;
Half2: 0..UInt64(1 shl 63)-1;
end;
TRec64_v2 = bitpacked record
Half1: 0..UInt64(1 shl 16)-1;
Half2: 0..UInt64(1 shl 48)-1;
end;
begin
writeln('sizeof TRec64_v0: ', sizeof(TRec64_v0));
writeln('sizeof TRec64_v1: ', sizeof(TRec64_v1));
writeln('sizeof TRec64_v2: ', sizeof(TRec64_v2));
readln;
end.
Refer to the forum thread: https://forum.lazarus.freepascal.org/index.php/topic,73071.msg572758.html#msg572758 for additional examples that exhibit the problem as well as versions of FPC that have been tested for it. Be particularly conscious that there are cases when the record size will be correct BUT, the offsets of fields that follow the bitfields are incorrect. An example of how to create that case is stated in the above thread.
What is the current bug behavior?
The calculated size of the record is incorrect.
What is the expected (correct) behavior?
The size of the record should be correct, not incorrect.
Relevant logs and/or screenshots
Refer to the forum thread: https://forum.lazarus.freepascal.org/index.php/topic,73071.msg572758.html#msg572758 for additional examples that exhibit the problem as well as versions of FPC that have been tested for it. Be particularly conscious that there are cases when the record size will be correct BUT, the offsets of fields that follow the bitfields are incorrect. An example of how to create that case is stated in the above thread.
Possible fixes
The compiler seems to calculate the size correctly when the sum of the bitfields is less than 64. This "remedy" has not yet been extensively tested, IOW, it is not known if it works in all cases but, it does work in all tested cases.