------- Comment #1 from burnus at gcc dot gnu dot org 2009-11-02 21:23 ------- Actually, it is not as simple as it seems. Currently, one gets for
subroutine one(a) integer, dimension(:) :: a call two(a) end subroutine one subroutine two(a) integer, dimension(:) :: a end subroutine two the following dump: one (struct array1_integer(kind=4) & restrict a) { integer(kind=8) ubound.0; integer(kind=8) stride.1; integer(kind=8) offset.2; integer(kind=8) size.3; integer(kind=4)[0:D.1401] * restrict a.0; integer(kind=8) D.1401; bit_size_type D.1402; <unnamed-unsigned:64> D.1403; { integer(kind=8) D.1400; D.1400 = a->dim[0].stride; stride.1 = D.1400 != 0 ? D.1400 : 1; a.0 = (integer(kind=4)[0:D.1401] * restrict) a->data; ubound.0 = (a->dim[0].ubound - a->dim[0].lbound) + 1; size.3 = stride.1 * NON_LVALUE_EXPR <ubound.0>; offset.2 = -stride.1; D.1401 = size.3 + -1; D.1402 = (bit_size_type) size.3 * 32; D.1403 = (<unnamed-unsigned:64>) size.3 * 4; } { integer(kind=8) D.1399; integer(kind=8) D.1398; struct array1_integer(kind=4) parm.4; integer(kind=8) D.1394; D.1394 = ubound.0; parm.4.dtype = 265; D.1398 = offset.2; D.1399 = stride.1; parm.4.dim[0].lbound = 1; parm.4.dim[0].ubound = D.1394; parm.4.dim[0].stride = NON_LVALUE_EXPR <D.1399>; parm.4.data = (void *) &(*a.0)[0]; parm.4.offset = NON_LVALUE_EXPR <D.1398>; two (&parm.4); } } In principle. passing "two(&a)" would be sufficient. However: The "a -> a.0" conversion happens at the very beginning of the procedure (trans-decl.c I presume). Passing "a.0" (== parmse.expr in gfc_conv_procedure_call) is wrong as "a.0" is not a descriptor but just a pointer to the (noncontiguous) array. Passing "a" as in "two (&a)" is presumably also wrong as this presumably collides with "restricted". * * * One way out would be -- assuming ABI breakage -- to do the same conversion for the caller but then do not do conversion in the callee. Thus: one (struct array1_integer(kind=4) & restrict a) { a.data[0] = 5 rather than /* generate a whole stuff of plain variables used like a descriptor */ a.0[0] = 5 two (&a) That way one uses the restricted variable directly, and one saves the generation of a extra variables and arithmetic. The question is whether one needs to take care of things like: stride.1 = D.1400 != a->dim[0].stride ? D.1400 : 1; Actually, it might be no ABI breakage - assuming all descriptor variables are properly initialized in current 4.(3-5). One needs to check this. -- burnus at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- AssignedTo|burnus at gcc dot gnu dot |unassigned at gcc dot gnu |org |dot org Status|ASSIGNED |NEW http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41911