Hi Paul, Andre,

at the risk of getting stoned to death, here's an example:

module m
  implicit none
  integer :: c
contains
  function f(n) result(z)
    integer,  intent(in) :: n
    character, parameter :: c(3) = ['x', 'y', 'z']
    character(len_trim(c(n)))  :: z
    z = c(n)
  end
  function h(n) result(z)
    integer,  intent(in) :: n
    character, parameter :: c(3,3) = 'x'
    character(len_trim(c(n,n)))  :: z
    z = c(n,n)
  contains
    function k(n) result(z)
      integer,  intent(in) :: n
      character, parameter :: c(3) = ['*', '+', '-']
      character(len_trim(c(n)))  :: z
      z = c(n)
    end
  end
end
program p
  use m
  implicit none
  print *, f(2)
  print *, h(1)
end

% gfc-15 pr84868-z0.f90 -fdump-fortran-original

Namespace: A-Z: (UNKNOWN 0)
procedure name = m
  symtree: '@0'          || symbol: '_len_trim_c_h' from namespace 'h'
  symtree: '@1'          || symbol: '_len_trim_c_k' from namespace 'k'
  symtree: '@2'          || symbol: '_len_trim_c_f' from namespace 'f'
  symtree: 'c'           || symbol: 'c'
[...]
f951: internal compiler error: in gfc_create_module_variable, at
fortran/trans-decl.cc:5515
0x2438776 internal_error(char const*, ...)
        ../../gcc-trunk/gcc/diagnostic-global-context.cc:491
0x96df24 fancy_abort(char const*, int, char const*)
        ../../gcc-trunk/gcc/diagnostic.cc:1725
0x752d8a gfc_create_module_variable
        ../../gcc-trunk/gcc/fortran/trans-decl.cc:5515
0x752d8a gfc_create_module_variable
        ../../gcc-trunk/gcc/fortran/trans-decl.cc:5428
[...]

So you are very close!

My example is likely very artificial, but nevertheless legal.

We hit the following assert:

  gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
              || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
                  && sym->fn_result_spec));

For '_len_trim_c_k':

Breakpoint 1, gfc_create_module_variable (sym=0x32af2f0)
    at ../../gcc-trunk/gcc/fortran/trans-decl.cc:5515
5515      gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
(gdb) p sym->ns->proc_name->attr.flavor
$9 = FL_PROCEDURE
(gdb) p sym->ns->parent->proc_name->attr.flavor
$10 = FL_PROCEDURE

This is not good.

Can we prevent the export of this artificial symbol?

Otherwise the patch is fine.

Thanks,
Harald


Am 15.07.24 um 12:23 schrieb Andre Vehreschild:
Hi Paul,

I tried to "break" your patch, but I failed. (I tried having same function in
both modules with identical signature; but I do not get a symbol collision). So
to me the patch looks fine now. But you may want to give Harald some time for a
look.

Thanks for the patch,
        Andre

On Mon, 15 Jul 2024 10:41:45 +0100
Paul Richard Thomas <paul.richard.tho...@gmail.com> wrote:

I've done it again! Patch duly added.

Paul

On Mon, 15 Jul 2024 at 09:21, Paul Richard Thomas <
paul.richard.tho...@gmail.com> wrote:

Hi Harald,

Thank you for the review and for the testing to destruction. Both issues
are fixed in the attached patch. Note the new function 'h', which both
tests that the namespace confusion is fixed and that the elemental-ness of
LEN_TRIM is respected.

The patch continues to regtest OK. If I don't receive anymore
comments/corrections, I will commit tomorrow morning.

Regards

Paul


On Sun, 14 Jul 2024 at 19:50, Harald Anlauf <anl...@gmx.de> wrote:

Hi Paul,

at first sight the patch seems to be the right approach, but
it breaks for the following two variations:

(1) LEN_TRIM is elemental, but the following is erroneously rejected:

    function g(n) result(z)
      integer,  intent(in) :: n
      character, parameter :: d(3,3) = 'x'
      character(len_trim(d(n,n))) :: z
      z = d(n,n)
    end

This is fixed here by commenting/removing the line

        expr->rank = 1;

as the result shall have the same shape as the argument.
Can you check?

(2) The handling of namespaces is problematic: using the same name
for a parameter within procedures in the same scope generates another
ICE.  The following testcase demonstrates this:

module m
    implicit none
    integer :: c
contains
    function f(n) result(z)
      integer,  intent(in) :: n
      character, parameter :: c(3) = ['x', 'y', 'z']
      character(len_trim(c(n)))  :: z
      z = c(n)
    end
    function h(n) result(z)
      integer,  intent(in) :: n
      character, parameter :: c(3,3) = 'x'
      character(len_trim(c(n,n)))  :: z
      z = c(n,n)
    end
end
program p
    use m
    implicit none
    print *, f(2)
    print *, h(1)
end

I get:

pr84868-z0.f90:22:15:

     22 |   print *, h(1)
        |               1
internal compiler error: in gfc_conv_descriptor_stride_get, at
fortran/trans-array.cc:483
0x243e156 internal_error(char const*, ...)
          ../../gcc-trunk/gcc/diagnostic-global-context.cc:491
0x96dd70 fancy_abort(char const*, int, char const*)
          ../../gcc-trunk/gcc/diagnostic.cc:1725
0x749d68 gfc_conv_descriptor_stride_get(tree_node*, tree_node*)
          ../../gcc-trunk/gcc/fortran/trans-array.cc:483
[rest of traceback elided]

Renaming the parameter array in h solves the problem.

Am 13.07.24 um 17:57 schrieb Paul Richard Thomas:
Hi All,

Harald has pointed out that I attached the ChangeLog twice and the patch
not at all :-(

Please find the patch duly attached.

Paul


On Sat, 13 Jul 2024 at 10:58, Paul Richard Thomas <
paul.richard.tho...@gmail.com> wrote:

Hi All,

After messing around with argument mapping, where I found and fixed
another bug, I realised that the problem lay with simplification of
len_trim with an argument that is the element of a parameter array.
The fix
was then a straightforward lift of existing code in expr.cc. The
mapping
bug is also fixed by supplying the se string length when building
character
typespecs.

Regtests just fine. OK for mainline? I believe that this is safe for
backporting to 14-branch before the 14.2 release - thoughts?

If you manage to correct/fix the above issues, I am fine with
backporting, as this appears a very reasonable fix.

Thanks,
Harald

Regards

Paul






--
Andre Vehreschild * Email: vehre ad gmx dot de


Reply via email to