[fortran] Re: Make array_at_struct_end_p to grok MEM_REFs

Jan Hubicka hubicka@ucw.cz
Mon May 23 16:32:00 GMT 2016


> 
> The assert below is unnecessary btw - it is ensured by IL checking.
I removed the assert but had to add a check that sizes match. As sported by the
testsuite, the declaration size doesn't need to match the size of object that we
see.
> 
> Rather than annotating an ARRAY_REF I'd have FEs annotate FIELD_DECLs
> that they are possibly flexible-size members.

This was my original plan. The problem however is that in many cases we do
not see any FIELD_DECL.  When I dump the Fortran cases we give up on, I typically
see something like:
Index: trans-types.c
===================================================================
--- trans-types.c       (revision 236556)
+++ trans-types.c       (working copy)
@@ -1920,7 +1920,7 @@ gfc_get_array_type_bounds (tree etype, i
 
   /* We define data as an array with the correct size if possible.
      Much better than doing pointer arithmetic.  */
-  if (stride)
+  if (stride && akind >= GFC_ARRAY_ALLOCATABLE)
     rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node,
                              int_const_binop (MINUS_EXPR, stride,
                                               build_int_cst (TREE_TYPE (stride), 1)));

It does not seem to make sense to build range types for arrays where the
permitted value range is often above the upper bound.

In that case I think we may just add ARRAY_TYPE_STRICT_DOMAIN flag 
specifying that the value must be within the given range. Then we can just
build arrays with strict ranges when we know these are not trailing.

Honza
> 
> Richard.
> 

	* tree.c (array_at_struct_end_p): Look through MEM_REF.
Index: tree.c
===================================================================
--- tree.c	(revision 236529)
+++ tree.c	(working copy)
@@ -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;



More information about the Gcc-patches mailing list