tree.c (array_at_struct_end_p): Handle arrays at struct end with flexarrays more...
authorRichard Biener <rguenther@suse.de>
Thu, 4 May 2017 09:08:01 +0000 (09:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 4 May 2017 09:08:01 +0000 (09:08 +0000)
2017-05-04  Richard Biener  <rguenther@suse.de>

* tree.c (array_at_struct_end_p): Handle arrays at struct
end with flexarrays more conservatively.  Refactor and treat
arrays of arrays or aggregates more strict.  Fix
VIEW_CONVERT_EXPR handling.  Remove allow_compref argument.
* tree.c (array_at_struct_end_p): Adjust prototype.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust.
* gimple-fold.c (get_range_strlen): Likewise.
* tree-chkp.c (chkp_may_narrow_to_field): Likewise.

From-SVN: r247581

gcc/ChangeLog
gcc/emit-rtl.c
gcc/gimple-fold.c
gcc/tree-chkp.c
gcc/tree.c
gcc/tree.h

index c690da95a26ae2939fd05b9d4eda603e2955feb5..1c01a1571c23e50891cb9e08d4fe352197370240 100644 (file)
@@ -1,3 +1,14 @@
+2017-05-04  Richard Biener  <rguenther@suse.de>
+
+       * tree.c (array_at_struct_end_p): Handle arrays at struct
+       end with flexarrays more conservatively.  Refactor and treat
+       arrays of arrays or aggregates more strict.  Fix
+       VIEW_CONVERT_EXPR handling.  Remove allow_compref argument.
+       * tree.c (array_at_struct_end_p): Adjust prototype.
+       * emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust.
+       * gimple-fold.c (get_range_strlen): Likewise.
+       * tree-chkp.c (chkp_may_narrow_to_field): Likewise.
+
 2017-05-04  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/31130
index d7aba8864beac8c96f7b61c00a6e16b860302c78..041f2a717607fb273b87c0570367f3a9bd40e7ad 100644 (file)
@@ -1957,7 +1957,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
              || (TREE_CODE (t2) == COMPONENT_REF
                  /* For trailing arrays t2 doesn't have a size that
                     covers all valid accesses.  */
-                 && ! array_at_struct_end_p (t, false)))
+                 && ! array_at_struct_end_p (t)))
            {
              attrs.expr = t2;
              attrs.offset_known_p = false;
index 5ebdcdfd796f983255d13f939628253ff689d9d3..d58f62207fa5dfe6dc8ee705b131eb6fe52f24e7 100644 (file)
@@ -1235,7 +1235,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
                 the NUL.
                 Set *FLEXP to true if the array whose bound is being
                 used is at the end of a struct.  */
-             if (array_at_struct_end_p (arg, true))
+             if (array_at_struct_end_p (arg))
                *flexp = true;
 
              arg = TREE_OPERAND (arg, 1);
index b1ff21851c6a0aa2602c7a658944cf200bcaa0af..23f5af98ae3d5b84488a11ac609c1b5f4eadc842 100644 (file)
@@ -3277,7 +3277,7 @@ chkp_may_narrow_to_field (tree ref, tree field)
   return DECL_SIZE (field) && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST
     && tree_to_uhwi (DECL_SIZE (field)) != 0
     && !(flag_chkp_flexible_struct_trailing_arrays
-        && array_at_struct_end_p (ref, true))
+        && array_at_struct_end_p (ref))
     && (!DECL_FIELD_OFFSET (field)
        || TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST)
     && (!DECL_FIELD_BIT_OFFSET (field)
index d88c445d32bc8628b90784bd165929b1c9a32c60..3bc6f1c284d2e0ae6a1263adfbca512d50a0b99f 100644 (file)
@@ -13221,18 +13221,26 @@ array_ref_up_bound (tree exp)
   return NULL_TREE;
 }
 
-/* Returns true if REF is an array reference to an array at the end of
-   a structure.  If this is the case, the array may be allocated larger
-   than its upper bound implies.  When ALLOW_COMPREF is true considers
-   REF when it's a COMPONENT_REF in addition ARRAY_REF and
-   ARRAY_RANGE_REF.  */
+/* Returns true if REF is an array reference or a component reference
+   to an array at the end of a structure.
+   If this is the case, the array may be allocated larger
+   than its upper bound implies.  */
 
 bool
-array_at_struct_end_p (tree ref, bool allow_compref)
+array_at_struct_end_p (tree ref)
 {
-  if (TREE_CODE (ref) != ARRAY_REF
-      && TREE_CODE (ref) != ARRAY_RANGE_REF
-      && (!allow_compref || TREE_CODE (ref) != COMPONENT_REF))
+  tree atype;
+
+  if (TREE_CODE (ref) == ARRAY_REF
+      || TREE_CODE (ref) == ARRAY_RANGE_REF)
+    {
+      atype = TREE_TYPE (TREE_OPERAND (ref, 0));
+      ref = TREE_OPERAND (ref, 0);
+    }
+  else if (TREE_CODE (ref) == COMPONENT_REF
+          && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE)
+    atype = TREE_TYPE (TREE_OPERAND (ref, 1));
+  else
     return false;
 
   while (handled_component_p (ref))
@@ -13240,19 +13248,42 @@ array_at_struct_end_p (tree ref, bool allow_compref)
       /* If the reference chain contains a component reference to a
          non-union type and there follows another field the reference
         is not at the end of a structure.  */
-      if (TREE_CODE (ref) == COMPONENT_REF
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+      if (TREE_CODE (ref) == COMPONENT_REF)
        {
-         tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
-         while (nextf && TREE_CODE (nextf) != FIELD_DECL)
-           nextf = DECL_CHAIN (nextf);
-         if (nextf)
-           return false;
+         if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+           {
+             tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
+             while (nextf && TREE_CODE (nextf) != FIELD_DECL)
+               nextf = DECL_CHAIN (nextf);
+             if (nextf)
+               return false;
+           }
        }
+      /* If we have a multi-dimensional array we do not consider
+         a non-innermost dimension as flex array if the whole
+        multi-dimensional array is at struct end.
+        Same for an array of aggregates with a trailing array
+        member.  */
+      else if (TREE_CODE (ref) == ARRAY_REF)
+       return false;
+      else if (TREE_CODE (ref) == ARRAY_RANGE_REF)
+       ;
+      /* If we view an underlying object as sth else then what we
+         gathered up to now is what we have to rely on.  */
+      else if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
+       break;
+      else
+       gcc_unreachable ();
 
       ref = TREE_OPERAND (ref, 0);
     }
 
+  /* The array now is at struct end.  Treat flexible arrays as
+     always subject to extend, even into just padding constrained by
+     an underlying decl.  */
+  if (! TYPE_SIZE (atype))
+    return true;
+
   tree size = NULL;
 
   if (TREE_CODE (ref) == MEM_REF
index 21c7220111074a80d54aeb6328541f768b5d3ed7..1b7d86a5257d3b2b25b1457960c986a39df2821c 100644 (file)
@@ -4886,12 +4886,10 @@ extern tree array_ref_up_bound (tree);
    EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
 extern tree array_ref_low_bound (tree);
 
-/* Returns true if REF is an array reference to an array at the end of
-   a structure.  If this is the case, the array may be allocated larger
-   than its upper bound implies.  When second argument is true considers
-   REF when it's a COMPONENT_REF in addition ARRAY_REF and
-   ARRAY_RANGE_REF.  */
-extern bool array_at_struct_end_p (tree, bool = false);
+/* Returns true if REF is an array reference or a component reference
+   to an array at the end of a structure.  If this is the case, the array
+   may be allocated larger than its upper bound implies.  */
+extern bool array_at_struct_end_p (tree);
 
 /* Return a tree representing the offset, in bytes, of the field referenced
    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */