On Mon, 23 May 2016, Jan Hubicka wrote: > > > > 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.
Well, the ME explicitely allows domains with NULL TYPE_MAX_VALUE for this. In the above case TYPE_MIN_VALUE is zero so you can omit the domain but I believe that usually the FE communicates a lower bound of one to the ME. > 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)) But it's still an array at struct end. So I don't see how you can validly claim it is not. Richard. > && !(flag_unconstrained_commons > && TREE_CODE (ref) == VAR_DECL && DECL_COMMON (ref))) > return false; > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)