On Tue, 3 Apr 2012, Eric Botcazou wrote:
> > Hmm, yeah. Or something like
> > Index: expr.c
> > ===================================================================
> > --- expr.c (revision 186082)
> > +++ expr.c (working copy)
> > @@ -4490,8 +4490,8 @@ get_bit_range (unsigned HOST_WIDE_INT *b
> > bitoffset += (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
> > - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
> > - *bitstart = bitpos - bitoffset;
> > - *bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1;
> > + *bitstart = bitpos < (HOST_WIDE_INT) bitoffset ? 0 : bitpos -
> > bitoffset;
> > + *bitend = bitpos + tree_low_cst (DECL_SIZE (repr), 1) - bitoffset - 1;
> > }
> > /* Returns true if the MEM_REF REF refers to an object that does not
> > which conservatively truncates the bitrange.
> What do you think about allowing get_bit_range to adjust offset and bitpos?
> tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
> &unsignedp, &volatilep, true);
> if (TREE_CODE (to) == COMPONENT_REF
> && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
> get_bit_range (&bitregion_start, &bitregion_end, &offset, &bitpos, to);
> so as to have a really non-negative bitregion_start/bitregion_end? It would
> assert that offset is already non-null in that case.
For the case in question offset is (D.2640_7 + -1) * 20 + 16. I wonder
why DECL_FIELD_OFFSET of the outermost COMPONENT_REF is not added
to bitpos by get_inner_reference (that is what get_bit_range assumes ...).
The FIELD_DECL is
arg 1 <field_decl 0x7ffff5c50000 n type <integer_type 0x7ffff5c4f2a0
unsigned external packed bit-field nonaddressable SI file
pack18_pkg.ads line 10 col 7
size <integer_cst 0x7ffff5ae4c80 constant visited 31> unit size
<integer_cst 0x7ffff5ae4260 4>
align 1 offset_align 128
offset <integer_cst 0x7ffff5ae4420 constant visited 16>
bit offset <integer_cst 0x7ffff5ae4560 constant visited 1>
bit_field_type <integer_type 0x7ffff5c4f2a0 natural___XDLU_0__2147483647>
context <record_type 0x7ffff5c4f0a8 pack18_pkg__rec>>>
and TREE_OPERAND (to, 2) is NULL and component_ref_field_offset
returns 16. In the alias-oracle variants we add constant field-offsets
to the bitposition part (at least that avoids the need to dissect
the constant part of the offset from the non-constant part).
So, how would you make sure this works? Match the fact that
get_inner_reference does _not_ add DECL_FIELD_OFFSET to bitpos,
and, if DECL_FIELD_OFFSET is an INTEGER_CST simply subtract that
from offset and add it to bitpos? I suppose that would work.
Though doing that in get_inner_reference for DECL_BIT_FIELD_TYPE
fields may make sense as well.