re PR middle-end/58941 (value modification on zero-length array optimized away)
authorRichard Biener <rguenther@suse.de>
Tue, 5 Nov 2013 13:24:13 +0000 (13:24 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 5 Nov 2013 13:24:13 +0000 (13:24 +0000)
2013-11-05  Richard Biener  <rguenther@suse.de>

PR middle-end/58941
* tree-dfa.c (get_ref_base_and_extent): Merge common code
in MEM_REF and TARGET_MEM_REF handling.  Make sure to
process trailing array detection before diving into the
view-converted object (and possibly apply some extra offset).

* gcc.dg/torture/pr58941.c: New testcase.

From-SVN: r204391

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr58941.c [new file with mode: 0644]
gcc/tree-dfa.c

index 514b97e0059d563b606996a20315d3fe3d495b55..757eded9a1422eefa346e85b9dd556d1f5344056 100644 (file)
@@ -1,3 +1,11 @@
+2013-11-05  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/58941
+       * tree-dfa.c (get_ref_base_and_extent): Merge common code
+       in MEM_REF and TARGET_MEM_REF handling.  Make sure to
+       process trailing array detection before diving into the
+       view-converted object (and possibly apply some extra offset).
+
 2013-11-05  Joseph Myers  <joseph@codesourcery.com>
 
        * config/i386/i386.c (ix86_float_exceptions_rounding_supported_p):
index b33fcad60da01400bceae04b5c262de5cef65ff3..75abe6d1711525420a90d527d76ddc18c34dbc0f 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-05  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/58941
+       * gcc.dg/torture/pr58941.c: New testcase.
+
 2013-11-05  Marc Glisse  <marc.glisse@inria.fr>
 
        PR tree-optimization/58958
diff --git a/gcc/testsuite/gcc.dg/torture/pr58941.c b/gcc/testsuite/gcc.dg/torture/pr58941.c
new file mode 100644 (file)
index 0000000..c0eea07
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+typedef struct {
+    int msgLength;
+    unsigned char data[1000];
+} SMsg;
+
+typedef struct {
+    int dummy;
+    int d[0];
+} SData;
+
+int condition = 3;
+
+int main()
+{
+  SMsg msg;
+  SData *pData = (SData*)(msg.data);
+  unsigned int i = 0;
+  for (i = 0; i < 1; i++)
+    {
+      pData->d[i] = 0;
+      if(condition & 1)
+       pData->d[i] |= 0x55;
+      if(condition & 2)
+       pData->d[i] |= 0xaa;
+    }
+  if (pData->d[0] != 0xff)
+    abort ();
+  return 0;
+}
index a44cfe884dd941404a9bc0f27fb55326389cd31d..c8b257ea2903638c72f9e4e7ac8174eb8554f5da 100644 (file)
@@ -389,7 +389,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
   double_int bit_offset = double_int_zero;
   HOST_WIDE_INT hbit_offset;
   bool seen_variable_array_ref = false;
-  tree base_type;
 
   /* First get the final access size from just the outermost expression.  */
   if (TREE_CODE (exp) == COMPONENT_REF)
@@ -420,8 +419,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
      and find the ultimate containing object.  */
   while (1)
     {
-      base_type = TREE_TYPE (exp);
-
       switch (TREE_CODE (exp))
        {
        case BIT_FIELD_REF:
@@ -544,42 +541,43 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
        case VIEW_CONVERT_EXPR:
          break;
 
+       case TARGET_MEM_REF:
+         /* Via the variable index or index2 we can reach the
+            whole object.  Still hand back the decl here.  */
+         if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
+             && (TMR_INDEX (exp) || TMR_INDEX2 (exp)))
+           {
+             exp = TREE_OPERAND (TMR_BASE (exp), 0);
+             bit_offset = double_int_zero;
+             maxsize = -1;
+             goto done;
+           }
+         /* Fallthru.  */
        case MEM_REF:
+         /* We need to deal with variable arrays ending structures such as
+            struct { int length; int a[1]; } x;           x.a[d]
+            struct { struct { int a; int b; } a[1]; } x;  x.a[d].a
+            struct { struct { int a[1]; } a[1]; } x;      x.a[0][d], x.a[d][0]
+            struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d]
+            where we do not know maxsize for variable index accesses to
+            the array.  The simplest way to conservatively deal with this
+            is to punt in the case that offset + maxsize reaches the
+            base type boundary.  This needs to include possible trailing
+            padding that is there for alignment purposes.  */
+         if (seen_variable_array_ref
+             && maxsize != -1
+             && (!bit_offset.fits_shwi ()
+                 || !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+                 || (bit_offset.to_shwi () + maxsize
+                     == (signed) TREE_INT_CST_LOW
+                           (TYPE_SIZE (TREE_TYPE (exp))))))
+           maxsize = -1;
+
          /* Hand back the decl for MEM[&decl, off].  */
          if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
            {
              if (integer_zerop (TREE_OPERAND (exp, 1)))
                exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-             else
-               {
-                 double_int off = mem_ref_offset (exp);
-                 off = off.lshift (BITS_PER_UNIT == 8
-                                   ? 3 : exact_log2 (BITS_PER_UNIT));
-                 off = off + bit_offset;
-                 if (off.fits_shwi ())
-                   {
-                     bit_offset = off;
-                     exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-                   }
-               }
-           }
-         goto done;
-
-       case TARGET_MEM_REF:
-         /* Hand back the decl for MEM[&decl, off].  */
-         if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
-           {
-             /* Via the variable index or index2 we can reach the
-                whole object.  */
-             if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
-               {
-                 exp = TREE_OPERAND (TMR_BASE (exp), 0);
-                 bit_offset = double_int_zero;
-                 maxsize = -1;
-                 goto done;
-               }
-             if (integer_zerop (TMR_OFFSET (exp)))
-               exp = TREE_OPERAND (TMR_BASE (exp), 0);
              else
                {
                  double_int off = mem_ref_offset (exp);
@@ -589,7 +587,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
                  if (off.fits_shwi ())
                    {
                      bit_offset = off;
-                     exp = TREE_OPERAND (TMR_BASE (exp), 0);
+                     exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
                    }
                }
            }
@@ -601,8 +599,17 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
 
       exp = TREE_OPERAND (exp, 0);
     }
- done:
 
+  /* We need to deal with variable arrays ending structures.  */
+  if (seen_variable_array_ref
+      && maxsize != -1
+      && (!bit_offset.fits_shwi ()
+         || !host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+         || (bit_offset.to_shwi () + maxsize
+             == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
+    maxsize = -1;
+
+ done:
   if (!bit_offset.fits_shwi ())
     {
       *poffset = 0;
@@ -614,24 +621,6 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
 
   hbit_offset = bit_offset.to_shwi ();
 
-  /* We need to deal with variable arrays ending structures such as
-       struct { int length; int a[1]; } x;           x.a[d]
-       struct { struct { int a; int b; } a[1]; } x;  x.a[d].a
-       struct { struct { int a[1]; } a[1]; } x;      x.a[0][d], x.a[d][0]
-       struct { int len; union { int a[1]; struct X x; } u; } x; x.u.a[d]
-     where we do not know maxsize for variable index accesses to
-     the array.  The simplest way to conservatively deal with this
-     is to punt in the case that offset + maxsize reaches the
-     base type boundary.  This needs to include possible trailing padding
-     that is there for alignment purposes.  */
-
-  if (seen_variable_array_ref
-      && maxsize != -1
-      && (!host_integerp (TYPE_SIZE (base_type), 1)
-         || (hbit_offset + maxsize
-             == (signed) TREE_INT_CST_LOW (TYPE_SIZE (base_type)))))
-    maxsize = -1;
-
   /* In case of a decl or constant base object we can do better.  */
 
   if (DECL_P (exp))