------- Comment #3 from kkojima at gcc dot gnu dot org 2006-06-26 23:10 ------- GDB says that TREE_TYPE of a.d is the 32-bit integer and its DECL_BIT_FIELD_TYPE is 64-bit when place_field processes a.e. place_field uses the size of TREE_TYPE of the previous bit filed when deciding whether a bit field to be packed with the previous one or not. It seems that this makes the ms-bitfiled code confused. The appended patch is to make place_field use DECL_BIT_FIELD_TYPE of the previous bit field instead of TREE_TYPE when comparing the size of consecutive bit fields. It works for the above testcase, though the thorough tests are needed.
--- ORIG/trunk/gcc/stor-layout.c 2006-06-13 09:06:36.000000000 +0900 +++ LOCAL/trunk/gcc/stor-layout.c 2006-06-26 16:44:31.000000000 +0900 @@ -1022,6 +1022,7 @@ place_field (record_layout_info rli, tre if (targetm.ms_bitfield_layout_p (rli->t)) { tree prev_saved = rli->prev_field; + tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL; /* This is a bitfield if it exists. */ if (rli->prev_field) @@ -1037,8 +1038,7 @@ place_field (record_layout_info rli, tre && !integer_zerop (DECL_SIZE (rli->prev_field)) && host_integerp (DECL_SIZE (rli->prev_field), 0) && host_integerp (TYPE_SIZE (type), 0) - && simple_cst_equal (TYPE_SIZE (type), - TYPE_SIZE (TREE_TYPE (rli->prev_field)))) + && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))) { /* We're in the middle of a run of equal type size fields; make sure we realign if we run out of bits. (Not decl size, @@ -1105,8 +1108,7 @@ place_field (record_layout_info rli, tre if (!DECL_BIT_FIELD_TYPE (field) || (prev_saved != NULL - ? !simple_cst_equal (TYPE_SIZE (type), - TYPE_SIZE (TREE_TYPE (prev_saved))) + ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)) : !integer_zerop (DECL_SIZE (field)) )) { /* Never smaller than a byte for compatibility. */ -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28161