https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126659
Bug ID: 126659
Summary: ASSOCIATE with array slice fails to create a
temporary, causing wrong results when passed to
explicit-shape dummy argument
Product: gcc
Version: 14.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: varunshah1801 at gmail dot com
Target Milestone: ---
When an array slice is passed directly to a function expecting an
explicit-shape array, gfortran correctly creates a temporary copy (via
_gfortran_internal_pack). However, when the same slice is accessed via an
ASSOCIATE name and that name is passed to the same function, gfortran fails to
create the temporary and incorrectly passes a contiguous block of memory (even
if the data is not contiguous). This violates the Fortran standard, which
requires a temporary copy for non-contiguous actual arguments passed to
explicit-shape dummies.
This is demonstrated in the following program:
module printer
implicit none
private
public :: r_to_string
contains
function r_to_string(r) result(string_r)
implicit none
integer, intent(in) :: r(3)
character(len=18) :: string_r
write(string_r, fmt="(3(I6))") r(1), r(2), r(3)
end function r_to_string
end module printer
program associate_test
use printer, only: r_to_string
implicit none
integer :: r_list(2, 3)
integer :: a, unit_a, unit_b
logical :: file_a_exists, file_b_exists
r_list(1, :) = (/ 0, 0, 0/)
r_list(2, :) = (/ 1, 1, 1 /)
inquire(file="r_dump_a.txt", exist=file_a_exists)
inquire(file="r_dump_b.txt", exist=file_b_exists)
if (file_a_exists) then
open(newunit=unit_a, file="r_dump_a.txt", status="replace",
action="write")
else
open(newunit=unit_a, file="r_dump_a.txt", status="new", action="write")
endif
if (file_b_exists) then
open(newunit=unit_b, file="r_dump_b.txt", status="replace",
action="write")
else
open(newunit=unit_b, file="r_dump_b.txt", status="new", action="write")
endif
do a = 1, 2
write(unit_a, fmt="(A)") r_to_string(r_list(a, :))
associate(r=>r_list(a, :))
write(unit_b, fmt="(A)") r_to_string(r)
end associate
enddo
close(unit_a)
close(unit_b)
end program associate_test
The files created by the program (r_dump_a.txt and r_dump_b.txt) should be
identical but they are not.
Compiled with:
gfortran with flags: -O0 -Wall -Wpedantic -Wextra -fsanitize=address,undefined
-std=f2008
gfortran configuration:
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/opt/apps/el9-fix/compilers/gcc/14.2.0/libexec/gcc/x86_64-pc-linux-gnu/14.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /tmp/slurm.6198358/gcc-14.2.0/configure
--prefix=/opt/apps/el9-fix/compilers/gcc/14.2.0 --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (GCC)