Findloc with allocatable character arrays gfortran

I have a program where I am using allocatable character arrays to read in and write out headers for files. Within this program, I also want to be able to search through the array for a specific header, and so I am using the findloc intrinsic function to do this. Here is a simple example program:

program main
    implicit none

    character(len=:),dimension(:),allocatable :: char_array

    allocate(character(len=100) :: char_array(3))
    char_array = ["hello", "world", "array"]

    print*, findloc(char_array,"hello")
    print*, findloc(char_array,"world")
    print*, findloc(char_array,"array")

end program main

When I compile and run this program with gfortran 9 (linux), everything works as expected and the correct indices (1,2, and 3) are printed to the screen. Compiled with gfortran 11 and 12, however, I get a segmentation fault for an invalid memory reference, and the backtrace points directly to the first line with findloc (line 9). It might be worth noting that if the array is not allocatable and is instead declared directly with its length and size, the program runs as expected with all previously mentioned versions of gfortran.

So my question is: is this a valid program and is this a bug with gfortran’s implementation of findloc or is this invalid and I was just lucky that it works in gfortran 9? It might also be interesting to test this program with ifort or ifx to see if they differ from this behaviour.

Maybe this is on purpose, but the allocate() statement in that program is redundant. The very next assignment statement reallocates the array to the new len=5 and size=3 values.

You can add the line

print*, len(char_array), size(char_array)

to verify the reallocation. Your code works on MacOS with GNU Fortran (Homebrew GCC 13.2.0) 13.2.0 and with NAG Fortran Compiler Release 7.1(Hanzomon) Build 7114.

1 Like

You are right about the redundant allocation, however, even without the allocation statement, I still get a segmentation fault as before.

1 Like

Problem still there with gfortran 13. I think you should report the bug @jaiken. All 3 of AMD flang, ifort and ifx printed 1 2 3 on successive lines. By the way, the allocate statement is unnecessary in the program because char_array was automatically reallocated (with len=5) by the next statement
char_array = ["hello", "world", "array"]
All 4 of the compilers I tried gave the same results (one good, three not) with and without the allocate statement.

As @Ronshepard sent his reply while I was testing @jaiken’s program and drafting my reply, and he found the code OK with GNU Fortran 13.2, while I confirmed the bug with what I had said was version 13, I had to check. My GNU Fortran is a slightly earlier version than @Ronshepard’s:
gcc version 13.1.0 (Ubuntu 13.1.0-8ubuntu1~22.04)
It seems that the Gfortran people fixed the bug between versions 13.1 and 13.2.

Thank you both @Harper and @RonShepard; I think that it is pretty obvious now that the segmentation fault is just a bug that was present for a couple versions of gfortran. I will just have to be careful about which version I compile with, but that isn’t a big problem.

1 Like

With GNU Fortran (GCC) 14.0.1 20240121 on Windows from Equation.com the program gives the expected output.

1 Like

Just for anyone who is interested or anyone who runs into this issue in the future, I found this bug report about the findloc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110288

The bug was present for gfortran version 11, 12, and 13. Fixes were implemented for gfortran-14 and backported for version 11, 12, and 13 on July 14th 2023, however, only gfortran-13 has had a new release (13.2) since and so the bug is still present in the current releases of gfortran-11 (11.4) and gfortran-12 (12.3). From what I understand, the next releases of gfortran-11 and gfortran-12 should have the bug fixed as well.

Thanks again to everyone who tested out my test program.

2 Likes

I have a very similar issue to this. Consider the following program

program main
  implicit none
  character(20) :: a(3)
  character(:), allocatable :: b
  integer :: ind

  a(1) = 'a'
  a(2) = 'b'
  a(3) = 'c'
  b = 'b'

  ind = findloc(a, b, 1)
  print*,ind

end program

When I run this on MacOS Apple Silicon with GNU Fortran (Homebrew GCC 13.2.0) 13.2.0, everything works as expected (ind has value 2). But when I instead run it on a Ubuntu ARM64 virtual machine with GNU Fortran (GCC) 11.2.0, the program prints 0 instead of the expected 2.

Was this same bug fixed with newer GNU releases? I can’t figure out how to update GNU on my virtual machine.

My output is opposite (GnuFortran on mac gives wrong result (0), while gfortran Ubuntu OS shows correct(2)).

Updated: Note that the gfortran on ubunutu has old version of gfortran. So after reading the whole thread, I found that later versions after 13.2.0, might provide correct result.

On MAC: GNU Fortran (Homebrew GCC 13.1.0) 13.1.0
  implicit none
  character(20) :: a(3)
  character(:), allocatable :: b
  integer :: ind

  a(1) = 'a'
  a(2) = 'b'
  a(3) = 'c'
  b = 'b'

  ind = findloc(a, b, 1)
  print*,ind

end
(base) ~: gfortran findloc_use_characters.f90 && ./a.out
           0
On GNU Fortran (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
gfortran findloc_use_characters.f90 && ./a.out
           2
1 Like

I have tested your program @nicholaswogan with gfortran 9.5, 10.5, 11.4, and 12.3 on Ubuntu 22.04.4 LTS (intel CPU). Versions 9.5 and 10.5 give the expected result of 2 and versions 11.4 and 12.3 give 0.

I suspect the bug you are experiencing is related to the one I experienced and so from what I can tell, the bug appeared at some point in gfortran 11 and is fixed for the current releases of gfortran 13 (13.3 but also fixed in 13.2) and gfortran 14 (14.1). I also expect the bug to be fixed in the next releases of gfortran 11 (11.5) and gfortran 12 (12.4) whenever they are released. See here for gcc (and hence gfortran) releases.

In Ubuntu, using

sudo apt install gfortran

will get you the most recent version of gfortran available for your version of Ubuntu. In my case (Ubuntu 22.04 LTS), this seems to only be gcc/gfortran 12.3. If you would prefer a new version of gcc/gfortran, you will probably need to upgrade your Ubuntu installation. There might be a way around this to install newer versions of gcc/gfortran but I doubt it is recommended.

Alternatively, you can install an older version of gcc/gfortran (before the bug appeared) by running the previous command while specifying the version. For example with gfortran-10:

sudo apt install gfortran-10

But note that you will need to invoke the compiler as

gfortran-10 program.f90 -o program

instead of

gfortran program.f90 -o program

Or if you use fpm you will need to specify the compiler:

fpm run --compiler gfortran-10
1 Like

I’ve tried the above snippet with Compiler Explorer, and gfortran 11.1–13.1 give the value 0 (consistently with the above posts). Gfortran with versions <= 10.xxx and >= 13.2 give the value 2, so they seem OK.

We can try all versions of gfortran here.

2 Likes

Thanks @septc. I had not heard of Compiler Explorer before, but it seems like a very useful tool.

1 Like