[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