[PATCH] PR fortran/100950 - ICE in output_constructor_regular_field, at varasm.c:5514

Tobias Burnus tobias@codesourcery.com
Wed Aug 18 10:22:37 GMT 2021


Hi Harald,

sorry for the belated review.

On 03.08.21 23:17, Harald Anlauf wrote:
>>> allocate(x%str2, source="abd")
>>> if (len (x%str)) /= 1) ...
>>> if (len (x%str2(1:2) /= 2) ...
>>> etc.
>>>
>>> Namely: Search the last_ref = expr->ref->next->next ...?
>>> and then check that lastref?
> The mentioned search is now implemented.
>
> 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.)

Regarding:

> Otherwise
> there would be a conflict/inconsistency with type parameter inquiry,
> see F2018:9.4.5(2):
>
> "A deferred type parameter of a pointer that is not associated or
> of an unallocated allocatable variable shall not be inquired about."

That's a requirement for the user not to do:
   character(len=:), allocatable :: str
   n = len(str)  ! unallocated 'str'

which makes sense as 'len(str)' is not meaningful in this case and
the compiler might even access invalid memory in this case
and definitely undefined memory.

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'.

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


> +static bool
> +substring_has_constant_len (gfc_expr *e)
> +{
> +  gfc_ref *ref;
> +  HOST_WIDE_INT istart, iend, length;
> +  bool equal_length = false;
> +
> +  if (e->ts.type != BT_CHARACTER || e->ts.deferred)
> +    return false;
cf. above.
> +
> +  for (ref = e->ref; ref; ref = ref->next)
> +    if (ref->type != REF_COMPONENT)
> +      break;
> +
> +  if (!ref
> +      || ref->type != REF_SUBSTRING
> +      || !ref->u.ss.start

With the caveat from above that len(<substring>) is rather special,
there is no real reason why:  str_array(:)(4:5)  cannot be handled.
(→ len = 2).

[I do note that "len(str(:5))" appears in your examples, hence,
I assume that ss.start is set in that case to '1'.]

> The updated patch regtests fine.  OK?
Looks good to me except for the caveats.

In particular:

  * * *

I think at least the array case should be handled.
On current mainline (i.e. without your patch),
I get (-fdump-tree-original)

   x = 5;  // Wrong - should be 1
   y = 1;  // OK

for

character(len=5) :: str2(4)
type t
    character(len=5) :: str(4)
end type t
type(t) :: var
integer :: x, y
x = len(var%str(:)(1:1))
y = len(str2(:)(1:1))
end

I don't know what's the result with your patch - but if
it is 'x = 5', it must be fixed.

  * * *

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.

  * * *

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.

Thanks,

Tobias

> Fortran - simplify length of substring with constant bounds
>
> gcc/fortran/ChangeLog:
>
>       PR fortran/100950
>       * simplify.c (substring_has_constant_len): New.
>       (gfc_simplify_len): Handle case of substrings with constant
>       bounds.
>
> gcc/testsuite/ChangeLog:
>
>       PR fortran/100950
>       * gfortran.dg/pr100950.f90: New test.

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955


More information about the Gcc-patches mailing list