My point is, the middle-end infrastructure makes it possible for this
case to appear, and it seems to be easy to handle conservatively.
There isn't a need to wait for users to run into an ICE or an assert we put
there IMHO. If I'd be fluent in Ada I'd write you a testcase, but I ain't.
Ughh, this is getting messier.
Ok, I propose keeping track of the field prior (lastfld), calling
get_inner_reference() and adding DECL_SIZE (or tbitsize if you prefer)
to calculate maxbits without the padding.
Notice the comment at the top. We can get rid of yet another call to
get_inner_reference later.
Is this what you had in mind?
BTW, we don't need to round up to the next byte here, do we?
Thanks.
Aldy
/* If we found the end of the bit field sequence, include the
padding up to the next field... */
if (fld)
{
tree end_offset, t;
HOST_WIDE_INT end_bitpos;
/* FIXME: Only call get_inner_reference once (at the beginning
of the bit region), and use
DECL_FIELD_OFFSET+DECL_FIELD_BIT_OFFSET throughout to
calculate any subsequent bit offset. */
/* Even if the bitfield we access (and thus the whole region) is
at a constant offset, the field _following_ the bitregion can
be at variable offset. In this case, do not include any
padding. This is mostly for Ada. */
if (TREE_CODE (DECL_FIELD_OFFSET (fld)) != INTEGER_CST)
{
get_inner_reference (build3 (COMPONENT_REF,
TREE_TYPE (exp),
TREE_OPERAND (exp, 0),
lastfld, NULL_TREE),
&tbitsize, &end_bitpos, &end_offset,
&tmode, &tunsignedp, &tvolatilep, true);
/* Calculate the size of the bit region up the last
bitfield, excluding any subsequent padding.
t = (end_byte_off - start_byte_offset) * 8 + end_bit_off */
end_offset = end_offset ? end_offset : size_zero_node;
t = fold_build2 (PLUS_EXPR, size_type_node,
fold_build2 (MULT_EXPR, size_type_node,
fold_build2 (MINUS_EXPR, size_type_node,
end_offset,
*byte_offset),
build_int_cst (size_type_node,
BITS_PER_UNIT)),
build_int_cst (size_type_node,
end_bitpos));
/* Add the bitsize of the last field. */
t = fold_build2 (PLUS_EXPR, size_type_node,
t, DECL_SIZE (lastfld));
*maxbits = tree_low_cst (t, 1);
return;
}
...
...
...