On Tue, 7 Apr 2015, Jakub Jelinek wrote: > Hi! > > bit_offset in get_inner_reference is offset_int (i.e. a wide_int larger than > address size). get_inner_reference has code to handle the case when > bit_offset is negative by splitting it into a byte offset and very small > positive bitpos, but on the following testcase bit_offset isn't negative, > just is too large to fit into shwi, so to the caller it incorrectly appears > to be negative. > > This patch fixes it by handling it the same, putting the large part into > offset and just the remaining bits into bitpos in that case. > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Thanks, Richard. > 2015-04-07 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/65680 > * expr.c (get_inner_reference): Handle bit_offset that doesn't fit > into signed HOST_WIDE_INT the same as negative bit_offset. > > * gcc.c-torture/compile/pr65680.c: New test. > > --- gcc/expr.c.jj 2015-03-16 17:06:30.000000000 +0100 > +++ gcc/expr.c 2015-04-07 10:16:10.365876617 +0200 > @@ -6941,7 +6941,7 @@ get_inner_reference (tree exp, HOST_WIDE > if (offset) > { > /* Avoid returning a negative bitpos as this may wreak havoc later. */ > - if (wi::neg_p (bit_offset)) > + if (wi::neg_p (bit_offset) || !wi::fits_shwi_p (bit_offset)) > { > offset_int mask = wi::mask <offset_int> (LOG2_BITS_PER_UNIT, false); > offset_int tem = bit_offset.and_not (mask); > --- gcc/testsuite/gcc.c-torture/compile/pr65680.c.jj 2015-04-07 > 10:25:40.142632657 +0200 > +++ gcc/testsuite/gcc.c-torture/compile/pr65680.c 2015-04-07 > 10:25:08.000000000 +0200 > @@ -0,0 +1,20 @@ > +/* PR middle-end/65680 */ > +/* { dg-do compile { target lp64 } } */ > + > +struct S > +{ > + int f : 1; > +} a[100000000000000001][3]; > + > +void > +foo (void) > +{ > + struct S b = { 0 }; > + a[100000000000000000][0] = b; > +} > + > +void > +bar (void) > +{ > + a[100000000000000000][0].f = 1; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)