Hi Tobias, > Gesendet: Mittwoch, 18. August 2021 um 12:22 Uhr > Von: "Tobias Burnus" > > Note, however, that gfc_simplify_len still won't handle neither > > deferred strings nor their substrings. > > > > I think there is nothing to simplify at compile time here. > > Obviously, nonsubstrings cannot be simplified but I do not > see why len(str(1:2)) cannot or should not be simplified. > > (Not that I regard substring length inquiries as that common.) well, here's an example that Intel rejects: type u character(8) :: s(4) character(:), allocatable :: str end type u type(u) :: q integer, parameter :: k2 = len (q% s(:)(3:4)) ! OK integer, parameter :: k3 = len (q% str (3:4)) ! Rejected by Intel print *, k2 if (k2 /= 2) stop 2 print *, k3 if (k3 /= 2) stop 3 end pr100950-ww.f90(7): error #6814: When using this inquiry function, the length of this object cannot be evaluated to a constant. [LEN] integer, parameter :: k3 = len (q% str (3:4)) ! Rejected by Intel -----------------------------^ pr100950-ww.f90(7): error #7169: Bad initialization expression. [LEN] integer, parameter :: k3 = len (q% str (3:4)) ! Rejected by Intel -----------------------------^ Of course we could accept it regardless what others do. I have therefore removed the check for deferred length in the attached patch (but read on). > However, there is no reason why the user cannot do: > if (allocated(str)) then > n = len(str) > m = len(str(5:8)) > end if > and why the compiler cannot replace the latter by 'm = 4'. Maybe you can enlighten me here. I thought one of the purposes of gfc_simplify_len is to evaluate constant expressions. Of course the length is constant, provided bounds are respected. Otherwise the result is, well, ... (It will then eveluate at runtime, which I thought was fine). > But, IMHO, the latter remark does _not_ imply that we > shall/must/have to accept code like: > > if (allocated(str)) then > block > integer, parameter :: n = len(str(:5)) > end block > endif So shall we not simplify here (and thus reject it)? This is important! Or silently simplify and accept it? > With the caveat from above that len() is rather special, > there is no real reason why: str_array(:)(4:5) cannot be handled. > (→ len = 2). Good point. This is fixed in the revised patch and tested for. > > The updated patch regtests fine. OK? > Looks good to me except for the caveats. Regtested again. > * * * > > And while the following works > > x = var%str(:)%len ! ok, yields 5 > y = str2(:)%len ! ok, yields 5 > > the following is wrongly rejected: > > x = var%str(:)(1:1)%len ! Bogus: 'Invalid character in name' > y = str2(:)(1:1)%len ! Bogus: 'Invalid character in name' > > (likewise with '%kind') > > (As "SUBSTRING % LEN", it also appears in the '16.9.99 INDEX', > but '9.4.5 Type parameter inquiry's 'R916 type-param-inquiry' > is the official reference.) > > If you don't want to spend time on this subpart - you could > fill a PR. Well, there's already https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101735 which is a much better suited place for discussion. > * * * > > For deferred length, I have no strong opinion; in > any case, the upper substring bound > stringlen check > cannot be done in that case (at compile time). I think > I slightly prefer doing the optimization – but as is > is a special case and has some caveats (must be allocated, > upper bound check not possible, ...) I also see reasons > not to do it. Hence, it also can remain as in your patch. Actually, this is now an important point. If we really want to allow to handle substrings of deferred length strings in constant expressions, the new patch would be fine, otherwise I would have to reintroduce the hunk + if (e->ts.deferred) + return NULL; and adjust the testcase. Your choice. See above. Of course there may be more corner cases which I did not think of... Thanks, Harald