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 
natural___XDLU_0__2147483647>
        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.

Richard.

Reply via email to