> I think we indeed can't really in stor-layout, so the only place is very > likely get_bit_range.
Something like that for example. I think the expmed.c hunk should be applied to the 4.7 branch as well, because the new code in store_bit_field is quite dangerous without it. * expmed.c (store_bit_field): Assert that BITREGION_START is a multiple of a unit before computing the offset in units. * expr.c (get_bit_range): Return the null range if the enclosing record is part of a larger bit field. -- Eric Botcazou
Index: expr.c =================================================================== --- expr.c (revision 185767) +++ expr.c (working copy) @@ -4462,6 +4462,25 @@ get_bit_range (unsigned HOST_WIDE_INT *b return; } + /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is + part of a larger bit field, then the representative does not serve any + useful purpose. This can occur in Ada. */ + if (handled_component_p (TREE_OPERAND (exp, 0))) + { + enum machine_mode rmode; + HOST_WIDE_INT rbitsize, rbitpos; + tree roffset; + int unsignedp; + int volatilep = 0; + get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos, + &roffset, &rmode, &unsignedp, &volatilep, false); + if ((rbitpos % BITS_PER_UNIT) != 0) + { + *bitstart = *bitend = 0; + return; + } + } + /* Compute the adjustment to bitpos from the offset of the field relative to the representative. DECL_FIELD_OFFSET of field and repr are the same by construction if they are not constants, Index: expmed.c =================================================================== --- expmed.c (revision 185570) +++ expmed.c (working copy) @@ -828,8 +828,7 @@ store_bit_field (rtx str_rtx, unsigned H /* Under the C++0x memory model, we must not touch bits outside the bit region. Adjust the address to start at the beginning of the bit region. */ - if (MEM_P (str_rtx) - && bitregion_start > 0) + if (MEM_P (str_rtx) && bitregion_start > 0) { enum machine_mode bestmode; enum machine_mode op_mode; @@ -839,6 +838,8 @@ store_bit_field (rtx str_rtx, unsigned H if (op_mode == MAX_MACHINE_MODE) op_mode = VOIDmode; + gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0); + offset = bitregion_start / BITS_PER_UNIT; bitnum -= bitregion_start; bitregion_end -= bitregion_start;