OSDN Git Service

PR c++/57793
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Jul 2013 05:53:35 +0000 (05:53 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Jul 2013 05:53:35 +0000 (05:53 +0000)
* expr.c (get_inner_reference): Avoid returning a negative bitpos.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@200862 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/c-c++-common/pr57793.c [new file with mode: 0644]

index aef3cb3..b6fdba6 100644 (file)
@@ -1,3 +1,8 @@
+2013-07-09  Jason Merrill  <jason@redhat.com>
+
+       PR c++/57793
+       * expr.c (get_inner_reference): Avoid returning a negative bitpos.
+
 2013-07-09  Joseph Myers  <joseph@codesourcery.com>
 
        * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Only
index 4c248e0..b66363c 100644 (file)
@@ -6698,7 +6698,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
                               ? 3 : exact_log2 (BITS_PER_UNIT),
                               HOST_BITS_PER_DOUBLE_INT, true);
       tem = double_int_add (tem, bit_offset);
-      if (double_int_fits_in_shwi_p (tem))
+      if (double_int_fits_in_shwi_p (tem) && !double_int_negative_p (tem))
        {
          *pbitpos = double_int_to_shwi (tem);
          *poffset = offset = NULL_TREE;
diff --git a/gcc/testsuite/c-c++-common/pr57793.c b/gcc/testsuite/c-c++-common/pr57793.c
new file mode 100644 (file)
index 0000000..7858a27
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR c++/57793 */
+
+struct A { unsigned a : 1; unsigned b : 1; };
+struct B
+{
+  unsigned char c[0x40000000];
+  unsigned char d[0x40000ff0];
+  struct A e;
+};
+
+void *foo (struct B *p)
+{
+  if (p->e.a)
+    return (void *) 0;
+  p->e.b = 1;
+  return p->c;
+}
+
+void
+bar (struct B *p)
+{
+  foo (p);
+}