On Fri, 30 Mar 2012, Eric Botcazou wrote:
> > > May I apply the patch I posted? It boostrapped/regtested fine on
> > > x86-64/Linux.
> > Yes.
> Thanks. Unfortunately, while this was the last identified problem on x86,
> another issue is visible on x86-64 as a miscompilation of XML/Ada at -O0.
> Reduced testcase attached:
> The executable segfaults because it attempts a read at 0x2000000000000000.
> The scenario is a follows: Rec is packed record so its fields are bit fields,
> being at bit offset 129. The representative is at offset 0.
> get_bit_range is invoked on N with a bitpos of 1, because there is variable
> offset and its DECL_FIELD_OFFFSET is added to it instead of bitpos. Hence
> bitpos - bitoffset
> is (unsigned HOST_WIDE_INT) -128. This value enters unchanged the new code
> store_bit_field and the division:
> offset = bitregion_start / BITS_PER_UNIT;
> yields the problematic big number.
> It would therefore appear that bitstart and bitend need to be signed offsets,
> at least until they are adjusted by store_bit_field.
Hmm, yeah. Or something like
--- 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 -
+ *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.