Dear Paul,

thanks for fixing the offset calculation.

Regarding:
> If variable is an allocated allocatable variable, it is deallocated if
> expr is an array of different shape or any of the corresponding length
> type parameter values of variable and expr differ. If variable is or
> becomes an unallocated allocatable variable, then it is allocated with
> each deferred type parameter equal to the corresponding type
> parameters of expr , with the shape of expr , and with each lower
> bound equal to the corresponding element of LBOUND(expr ).
> 
> In this case, 'expr' is reshape(b,shape(a),order=[3,2,1]), so the
> question is what should the lower bounds of this expression be?

One. For *nearly* all array expression, the lower bound is one. Including
arrays returned by functions, even if one has a result variable with
different bonds - and also for variables with array spec.

Thus for

  interface
    function f()
      integer :: f(-10:5)
    end function
  end interface
  integer :: array(0:10)

one always has:

  lbound ( array(4:6),     dim=1) == 1
  lbound ( array(:),       dim=1) == 1
  lbound ( array([1,6,8]), dim=1) == 1
  lbound ( f(),            dim=1) == 1
  lbound ( array * 2.0,    dim=1) == 1

However, for the variable itself without array specs ("whole array"),
one has - in this case -
  lbound (array, dim=1) == 0

>From the standard ("13.7.90 LBOUND (ARRAY [, DIM, KIND]", F2008):
"If ARRAY is a whole array and either ARRAY is an assumed-size array
 of rank DIM or dimension DIM of ARRAY has nonzero extent,
 LBOUND (ARRAY, DIM) has a value equal to the lower bound for
 subscript DIM of ARRAY. Otherwise the result value is 1."



> I would say that if 'variable' is already allocated, the existing
> lower bounds should be used, in order to be fortran-95 compatable.

Yes, exactly. Fortran 95 (and Fortran 2003/2008 if the LHS is not
allocatable) require that the LHS has the same shape as the RHS.

Thus, to be backward compatible, if an allocatable LHS has the same
shape as the RHS, no reallocation happens and the LHS bounds are the
same as before the intrinsic assignment.


> In practical terms, this means that the lbounds should be unity,

No. While most arrays do have a lower bound of unity, that's just a
default setting. One can declare or allocate or associate arrays with
whatever lower (co)bounds one would like to have:

  integer, target :: a(-1:5), b(-1:2), c(n:4,4:7), d[55:*]
  integer, allocatable :: e(:), f(:,:)[:,:]
  integer, pointer :: ptr
  allocate (e(44:99), f(-99:99, 0:5)[0:n, 4:*])
  ptr(44:) => b

For all those seven variables, none of the l(co)bounds is unity.


>  which is what is implemented.

I think - I have not tested the trunk after your commit
(Rev. 183757) - that it still mishandles

  integer, allocatable :: a(:), b(:)
  allocate(b(3))
  b = [1,2,3]

  allocate (a(7:9))
  a = reshape( b, shape=[size(b)])
  print *, lbound(a), ubound(a) ! Expected: 7 9
  end

As the LHS ("a") and the RHS ("reshape(b, shape=[3]") has
the same shape - namely "[ 3 ]", no reallocation is required and, thus,
the bounds of "a" remain as allocated, namely a(7:9).

That happens with 4.1 to 4.5 and with -fno-realloc-lhs with GCC 4.6 and 4.7.

I think that even with your patch (and -frealloc-lhs), the result will
be 1:3 instead of 7:9.


Unless I missed something when testing, the bound handling is otherwise
correct for external functions, whole arrays, intrinsic array operations
and those interinsic functions which are implemented inline instead of
(directly) invoking a libgfortran function.

Tobias

Reply via email to