pragma pack(<n>) fix
Mumit Khan
khan@xraylith.wisc.EDU
Fri Jun 11 21:33:00 GMT 1999
The following fixes the packing pragma code on x86-win32 for all the test
cases that I can come up with. Currently, it's horribly broken. Nick
Clifton and I had come up with a hack that Jason Merrill subsequently,
and justfiably so, removed (Mon Apr 26 21:17:41 1999) and that caused all
the bugs to show up right away. Currently, the system headers are being
compiled correctly for any of the x86-win32 ports except for Interix.
I'm attaching a set of 3 test cases, along with side-by-side comparison
with MSVC's output. Note how the pragma pack fails in almost cases except
for where #pragma pack(1) is specified. The testcases test all 5 possible
cases, <n>=1,2,4,8,16, for 3 different structures.
The main confusion arises from MS docs, which says the following:
Whe use #pragma pack(<n>), where <n> is 1, 2, 4, 8, or 16, each structure
member is after the first is stored on the smaller member type or <n>-
byte boundaries.
After much experimentation trying to figure out what this means, I believe
the "smaller member type ..." means that the members are aligned to the
*smaller* of natural alignment and specified packing <n>.
Many thanks to GrahamS <grahams@rcp.co.uk> for suggesting the fix!
The patch in push_alignment just corrects an omission in Jason's last
patch on 1999-04-26.
Fri Jun 11 22:09:13 1999 Mumit Khan <khan@xraylith.wisc.edu>
* c-pragma.c (push_alignment): Don't ignore alignments greater than
4 bytes.
(insert_pack_attributes): Take into account member natural
alignment.
Index: c-pragma.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95/gcc/c-pragma.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 c-pragma.c
--- c-pragma.c 1999/06/10 02:09:53 1.1.1.1
+++ c-pragma.c 1999/06/12 01:39:19
@@ -141,7 +141,7 @@ pop_alignment (id)
{
entry = alignment_stack->prev;
- if (entry == NULL || entry->alignment > 4)
+ if (entry == NULL)
maximum_field_alignment = 0;
else
maximum_field_alignment = entry->alignment * 8;
@@ -163,6 +163,7 @@ insert_pack_attributes (node, attributes
tree * prefix;
{
tree a;
+ int field_alignment;
/* If we are not packing, then there is nothing to do. */
if (maximum_field_alignment == 0
@@ -173,12 +174,16 @@ insert_pack_attributes (node, attributes
if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
|| TREE_CODE (node) != FIELD_DECL)
return;
+
+ field_alignment = TYPE_ALIGN (TREE_TYPE (node));
+ if (field_alignment <= 0 || field_alignment > maximum_field_alignment)
+ field_alignment = maximum_field_alignment;
/* Add a 'packed' attribute. */
* attributes = tree_cons (get_identifier ("packed"), NULL, * attributes);
/* If the alignment is > 8 then add an alignment attribute as well. */
- if (maximum_field_alignment > 8)
+ if (field_alignment > 8)
{
/* If the aligned attribute is already present then do not override it. */
for (a = * attributes; a; a = TREE_CHAIN (a))
@@ -201,7 +206,7 @@ insert_pack_attributes (node, attributes
* attributes = tree_cons
(get_identifier ("aligned"),
tree_cons (NULL,
- build_int_2 (maximum_field_alignment / 8, 0),
+ build_int_2 (field_alignment / 8, 0),
NULL),
* attributes);
}
Regards,
Mumit
More information about the Gcc-patches
mailing list