* tree.c (array_at_struct_end_p): Look through MEM_REF.
authorJan Hubicka <hubicka@ucw.cz>
Sat, 21 May 2016 09:46:22 +0000 (11:46 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 21 May 2016 09:46:22 +0000 (09:46 +0000)
From-SVN: r236557

gcc/ChangeLog
gcc/tree.c

index eee44b279723d71f94d8bd1b052a8b9fe97d075e..a4cdb4e1052ac848f7441591394673bec5d894b8 100644 (file)
@@ -1,3 +1,7 @@
+2016-05-21  Jan Hubicka  <hubicka@ucw.cz>
+
+       * tree.c (array_at_struct_end_p): Look through MEM_REF.
+
 2016-05-21  Kugan Vivekanandarajah  <kuganv@linaro.org>
 
        PR middle-end/71179
index 5a1d1676525d74b4463d3975ec95b2b8d895b0bb..83dc7d8bc900dab744157517b7b2a664c70a76ff 100644 (file)
@@ -13076,9 +13076,28 @@ array_at_struct_end_p (tree ref)
       ref = TREE_OPERAND (ref, 0);
     }
 
+  tree size = NULL;
+
+  if (TREE_CODE (ref) == MEM_REF
+      && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR)
+    {
+      size = TYPE_SIZE (TREE_TYPE (ref));
+      ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
+    }
+
   /* If the reference is based on a declared entity, the size of the array
      is constrained by its given domain.  (Do not trust commons PR/69368).  */
   if (DECL_P (ref)
+      /* Be sure the size of MEM_REF target match.  For example:
+
+          char buf[10];
+          struct foo *str = (struct foo *)&buf;
+
+          str->trailin_array[2] = 1;
+
+        is valid because BUF allocate enough space.  */
+
+      && (!size || operand_equal_p (DECL_SIZE (ref), size, 0))
       && !(flag_unconstrained_commons
           && TREE_CODE (ref) == VAR_DECL && DECL_COMMON (ref)))
     return false;