public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix get_inner_reference (PR middle-end/65680)
@ 2015-04-07 14:18 Jakub Jelinek
  2015-04-07 14:21 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2015-04-07 14:18 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix get_inner_reference (PR middle-end/65680)
  2015-04-07 14:18 [PATCH] Fix get_inner_reference (PR middle-end/65680) Jakub Jelinek
@ 2015-04-07 14:21 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2015-04-07 14:21 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

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

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-04-07 14:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-07 14:18 [PATCH] Fix get_inner_reference (PR middle-end/65680) Jakub Jelinek
2015-04-07 14:21 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).