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

            Bug ID: 124653
           Summary: gfortran accepts invalid atomic subroutine call in "do
                    concurrent" and in pure procedure
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: damian at archaeologic dot codes
  Target Milestone: ---

The Fortran 2023 Interpretation Document clause 16.1, paragraph 5 states

"The subroutine MOVE_ALLOC with noncoarray argument FROM, the subroutine SPLIT,
the subroutine TOKENIZE, and the elemental subroutine MVBITS, are simple. No
other standard intrinsic subroutine is pure or simple."

The program below demonstrates that gfortarn accepts atomic subroutines
references in a context that requires pure procedures:

$ cat atomic_example.F90 
program atomic_example
    use iso_fortran_env
    implicit none

    integer, parameter :: lim = 1000
    integer(atomic_int_kind) :: atomic_scalar[*]
    integer(atomic_int_kind) :: atomic_array(lim)[*]
    integer :: integer_array(lim)[*]
    integer :: i, n
    integer :: peer

    ! 1. Initialize variables
    call atomic_define(atomic_scalar, 0)
    do i = 1,lim
      call atomic_define(atomic_array(i), 0)
    end do
    integer_array = 0

    peer = 1+mod(this_image(), num_images())

    sync all

    ! Parallel loop using DO CONCURRENT
    do concurrent (i = 1:lim)

#     ifndef SKIP_ATOMIC_IN_DC
        ! Increment a scalar on image 1 (shared by all images, all iterations)
        call atomic_add(atomic_scalar[1], 1)

        ! increment/define some variables specific to this image and iteration
        call atomic_add(atomic_array(i)[peer], i)
#     endif

#     ifndef SKIP_ATOMIC_IN_PURE_SUB
        call pure_sub(atomic_array(i))
#     endif

#     ifdef CHECK_IMPURE_IN_DC
        call impure_sub()
#     endif

        integer_array(i)[peer] = i
    end do

    sync all


    if (this_image() == 1) then
      ! Print some final values
      call atomic_ref(n, atomic_scalar[1])
      print *, "atomic_scalar:    ", n
      call atomic_ref(n, atomic_array(5)[1])
      print *, "atomic_array(5):  ", n
      print *, "integer_array(5): ", integer_array(5)
    end if

contains

# ifndef SKIP_ATOMIC_IN_PURE_SUB
   pure subroutine pure_sub(atom)
     integer(atomic_int_kind), intent(inout) :: atom[*]
     call atomic_add(atom[peer], 10)
   end subroutine
# endif

  impure subroutine impure_sub()
  end subroutine

end program atomic_example

$ gfortran --version
GNU Fortran (GCC) 16.0.1 20260309 (experimental)


# gfortran accepts invalid code when calling atomic subroutines in do
concurrent constructs:
$ gfortran -fcoarray=single atomic_example.F90 

# gfortran correctly reports an error when the same subroutine is called from a
pure procedure:
$ gfortran -fcoarray=single -DCHECK_IMPURE_IN_DC atomic_example.F90 
atomic_example.F90:39:25:

   39 |         call impure_sub()
      |                         1
Error: Subroutine call to ‘impure_sub’ in DO CONCURRENT block at (1) is not
PURE
  • [Bug fortran/124653] New: gf... damian at archaeologic dot codes via Gcc-bugs

Reply via email to