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)

Reply via email to