This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix get_inner_reference (PR middle-end/65680)


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?

2015-04-07  Jakub Jelinek  <jakub@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]