https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118735

            Bug ID: 118735
           Summary: gfortran not following deferred initialization rules
                    for get_command_argument
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: andi.m.mcclure at gmail dot com
  Target Milestone: ---

Created attachment 60366
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60366&action=edit
File from first github link above

I believe I have found a nonconformance with gfortran 14.2.0 targeting the 2023
standard.

* Details

I wanted my program to input data from a file, and intended it to take the
filename from the command line. I found the standard way to do this is:

https://gcc.gnu.org/onlinedocs/gfortran/GET_005fCOMMAND_005fARGUMENT.html

The GNU docs' recommended usage of this function is to preallocate a character
array longer than the possible maximum and then trim. However, I had been
reading standards documents, and found this section in this 2023 "informal"
publication of the Fortran working group, "The new features of Fortran 2023"
https://wg5-fortran.org/N2201-N2250/N2212.pdf , emphasis mine:

> 2.2 US 14. Automatic allocation of lengths of character variables
> When a deferred-length allocatable variable is defined by intrinsic 
> assignment, as in the example
>
>     character(:), allocatable :: quotation
>     :
>     quotation = ’Now is the winter of our discontent.’
>
> it is allocated by the processor to the correct length. This behaviour is 
> extended to messages
> returned through iomsg and errmsg specifiers, writing to a scalar character 
> variable as an
> internal file, and intent out and inout scalar character arguments of 
> intrinsic procedures, **such
> as in call `get_command(command)`**.

This is an informal publication but I believe this should be taken to apply to
the "value" argument of GET_COMMAND_ARGUMENT, for three reasons: Because the
"new features" document explicitly calls out GET_COMMAND, and
GET_COMMAND_ARGUMENT is so similar; because the 2023 draft standard I find
https://j3-fortran.org/doc/year/23/23-007r1.pdf seems to confirm the behavior,
in 16.9.1: "When an allocatable deferred-length character scalar corresponding
to an INTENT (INOUT) or INTENT (OUT) argument is assigned a value, the value is
assigned as if by intrinsic assignment."; and because the same 2023 draft spec
states in GET_COMMAND_ARGUMENT that "value" is indeed INTENT(OUT).

If this spec section applied to GET_COMMAND_ARGUMENT it would be much
preferable because it would mean arguments of any length could be easily taken,
useful e.g. for long paths.

However, in my testing automatic allocation of the GET_COMMAND_ARGUMENT out
value does *not* work in gfortran. Here is a test program:

https://github.com/mcclure/aoc2024/blob/822e460f81b944c21ca675303b868c45b22a4c2b/04-01-wordsearch/src/puzzle.f90

I run this with `gfortran src/puzzle.f90 -std=f2023 -o program && ./program
data/puzzle.txt`. This program defines a character string as in the FORTRAN
2023 "new features" document (my source says "len=:" rather than ":", but
changing this to ":" does not change the output), passes the unallocated string
to GET_COMMAND_ARGUMENT, prints the string, then attempts to open a file by
that name. When print, the string appears to be empty; a blank line is printed,
followed by

> At line 20 of file src/puzzle.f90 (unit = 10)
> Fortran runtime error: Cannot open file '': No such file or directory

Here's a longer test program, with a long comment and a workaround; this passes
the string to GET_COMMAND_ARGUMENT but also a variable for the "length" out
parameter. It then allocates a string of that length and passes it to
GET_COMMAND_ARGUMENT. This works flawlessly (and you can confirm it actually is
opening the file by passing the name of a non-existent file as argument, which
the program will then create (because`action='read'` is not specified in the
open())):

https://github.com/mcclure/aoc2024/blob/b31be91adb5a0721f97e2ba8f145da4f36129753/04-01-wordsearch/src/puzzle.f90

* Summary

It is my opinion from the FORTRAN 2023 spec that the first test program above
should have worked, and the additional steps in the second test program should
not have been necessary.

I ran this by the GNU fortran mailing list and was told to file here.

* Configuration

I am using Debian Trixie on AMD64, I and installed gfortran from apt.

$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/14/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 14.2.0-12'
--with-bugurl=file:///usr/share/doc/gcc-14/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust --prefix=/usr
--with-gcc-major-version-only --program-suffix=-14
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace
--enable-gnu-unique-object --disable-vtable-verify --enable-plugin
--enable-default-pie --with-system-zlib --enable-libphobos-checking=release
--with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch
--disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none=/build/reproducible-path/gcc-14-14.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/reproducible-path/gcc-14-14.2.0/debian/tmp-gcn/usr
--enable-offload-defaulted --without-cuda-driver --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
--with-build-config=bootstrap-lto-lean --enable-link-serialization=3
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (Debian 14.2.0-12) 

Note: I have no pressing personal need for a fix for this, and my FORTRAN
project is now complete.

Reply via email to