------- Comment #4 from kkojima at gcc dot gnu dot org 2006-06-26 22:42 ------- Thanks for your comment. Perhaps one solution would be to handle such bit fields with excessive sizes as the case of "no remaining bits in alignment". I'm testing the appended patch which changes lines you've pointed out.
--- ORIG/trunk/gcc/stor-layout.c 2006-06-13 09:06:36.000000000 +0900 +++ LOCAL/trunk/gcc/stor-layout.c 2006-06-26 16:43:12.000000000 +0900 @@ -1047,17 +1047,20 @@ place_field (record_layout_info rli, tre if (rli->remaining_in_alignment < bitsize) { + HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1); + /* out of bits; bump up to next 'word'. */ - rli->offset = DECL_FIELD_OFFSET (rli->prev_field); rli->bitpos - = size_binop (PLUS_EXPR, TYPE_SIZE (type), - DECL_FIELD_BIT_OFFSET (rli->prev_field)); + = size_binop (PLUS_EXPR, rli->bitpos, + bitsize_int (rli->remaining_in_alignment)); rli->prev_field = field; - rli->remaining_in_alignment - = tree_low_cst (TYPE_SIZE (type), 1); + if (typesize < bitsize) + rli->remaining_in_alignment = 0; + else + rli->remaining_in_alignment = typesize - bitsize; } - - rli->remaining_in_alignment -= bitsize; + else + rli->remaining_in_alignment -= bitsize; } else { @@ -1119,9 +1121,16 @@ place_field (record_layout_info rli, tre if (DECL_SIZE (field) != NULL && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0) && host_integerp (DECL_SIZE (field), 0)) - rli->remaining_in_alignment - = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 1) - - tree_low_cst (DECL_SIZE (field), 1); + { + HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1); + HOST_WIDE_INT typesize + = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1); + + if (typesize < bitsize) + rli->remaining_in_alignment = 0; + else + rli->remaining_in_alignment = typesize - bitsize; + } /* Now align (conventionally) for the new type. */ type_align = TYPE_ALIGN (TREE_TYPE (field)); -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28160