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

            Bug ID: 118724
           Summary: [F08] Gfortran rejects passing a procedure as an
                    actual argument to a procedure pointer dummy argument
           Product: gcc
           Version: 14.2.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 2008 standard added a feature that allows for a procedure name to
be passed as the actual argument to a procedure pointer dummy argument. 
Gfortran rejects this.  The work around is to declare a procedure pointer, 
associate the pointer with the procedure name, and then pass the pointer as the
actual argument, which is relatively painless except unfortunately this is a
pattern that is used throughout  Berkeley Lab's Julienne unit testing framework
and in every project that uses Julienne as a testing framework so tripling the
lines of code generate quite a lot of workaround code across several projects.

In the example below, the preprocessor macro _GFORTRAN_ uses the work around to
enable the code to compile, but in each case it's the alternate code between
#else and #endif that is what I use with other compilers.

This at first looks like a duplicate of 67277, but I think that the code
originally submitted there is invalid because the procedure is an internal
subprogram rather than a module procedure so I'm submitting this separately
because I think 67277 might get marked as invalid at some point.


```
 % gfortran --version
GNU Fortran (Homebrew GCC 14.2.0_1) 14.2.0

% gfortran all.F90 
all.F90:35:22:

   35 |   test_description = test_description_t(do_something)
      |                      1
Error: Component 'test_function_' at (1) is a PRIVATE component of
'test_description_t'

%  cat all.F90 
module julienne_test_description_m
  implicit none

  private
  public :: test_description_t

  abstract interface
    function test_function_i() result(passed)
      implicit none
      logical passed
    end function
  end interface

  type test_description_t
    private
    procedure(test_function_i), pointer, nopass :: test_function_ => null()
  end type

  interface test_description_t
    module procedure construct_from_character_and_test_function
  end interface

contains
  function construct_from_character_and_test_function(test_function)
result(test_description)
    procedure(test_function_i), intent(in), pointer :: test_function
    type(test_description_t) test_description
    test_description%test_function_ => test_function
  end function
end module

program gfortran_reproducer
  use julienne_test_description_m
  implicit none
  type(test_description_t) test_description
  test_description = test_description_t(do_something)
contains
  logical function do_something()
    do_something = .false.
  end function
end program

Reply via email to