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;
        }
...
...
...

Reply via email to