On Sun, Nov 20, 2022 at 10:28:40PM +0100, Harald Anlauf via Fortran wrote: > Steve, > > for unknown reasons I cannot reply to your mail on gmane, > so trying directly via mailing list. > > I tried your patch, and it works on the supplied testcases. > > However, there is a scoping issue for the declaration of the > index variable, as can be seen by the following variation: > > program foo > use iso_fortran_env, only : k => real_kinds > implicit none > integer, parameter :: n = size(k) > integer(8) :: i > !!$ integer, parameter :: & > !!$ & p(n) = [(precision(real(1.,k(i))), integer :: i = 1, n)] > integer, parameter :: & > & q(n) = [(kind(i), integer(2) :: i = 1, n)] > integer, parameter :: & > & r(n) = [(storage_size(i), integer(1) :: i = 1, n)] > !!$ print *, p > print *, q > print *, r > end program foo > > After your patch, gfortran prints: > > 8 8 8 8 > 64 64 64 64 > > This suggests that the integer kind is taken from the host decl, > which is kind=8, and not the local one (2 or 1). > > Crayftn (which chokes on your original testcase): > > 3*2 > 3*8 > > This is what I expect. > > Intel doesn't accept storage_size() here, which is a bug. > Commenting the uses of array r, I then get: > > 2 2 2 > > At least this agrees with Cray. > > Can you have another look at this? >
Unfortunately, gfortran does not define a namespace for an implied-do index and uses a kludge by adding the attr.implied_index attribute to the symbol. Unfortunately**2, gfortran uses gfc_match_iterator for all places that 'i = start, stop [,step]' and there is no way to know if what is being parsed. With the introduction of an optional typespec, there is no easy way to deal with it in a clean way. Things get messy quickly when trying to deal with implicit typing and explicitly typed symbols. So, if the implied-do index has previously been typed such as integer(8) i print *, (i, integer(2) i=1, 3) the integer(2) is ignored. That's this part of the gfc_match_iterator diff + if (seen_ts && var->ts.type == BT_UNKNOWN) + { + var->ts.type = ts.type; + var->ts.kind = ts.kind; + var->symtree->n.sym->ts.type = ts.type; + var->symtree->n.sym->ts.kind = ts.kind; + } Perhaps, a better way would be to simply create a shadow symbol if a typespec appears in an iterator print *, (i, integer i=1,3) would become print *, (_i, integer _i=1,3) The issue is then that implied-do object list needs to be walked and all occurrence of i must be replaced with _i. -- Steve