Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a polymorphic assumed-rank entity as a selector in an select type construct #343

Open
kargl opened this issue Nov 1, 2024 · 2 comments

Comments

@kargl
Copy link

kargl commented Nov 1, 2024

To start with, here are two constraints from F2023:

C715:  An assumed-type variable name shall not appear in a designator or expression
except as an actual argument corresponding  to a dummy argument that is assumed-type,
or as the first argument to  the intrinsic function IS_CONTIGUOUS, LBOUND, PRESENT, RANK,
SHAPE, SIZE, or UBOUND, or the function C_LOC from the  intrinsic module ISO_C_BINDING.

C840:  An assumed-rank variable name shall not appear in a designator or expression except
as an actual argument that corresponds  to a dummy argument that is assumed-rank, the
argument of the function  C_LOC or C_SIZEOF from the intrinsic module ISO_C_BINDING (18.2),
the first dummy argument of an intrinsic inquiry function, or the selector of a SELECT RANK statement.

The following code compiles with both gfortran and flang (2024-11-01).

program foo

   implicit none

   integer, parameter :: sp = kind(1.e0), dp = kind(1.d0)

   integer i, j(2)
   real(sp) x, y(2)

   i = 1
   x = 42

   call bar(i)
   call bar(x)

   call bar(j)
   call bar(y)

   contains

      subroutine bar(a)

         class(*), intent(in) :: a(..)
         integer rnk
         integer, allocatable :: dims(:)
         character(len=:), allocatable :: str

         select rank (a)
         rank (0)
            rnk = 0
            dims = [1,1]
            select type(a)
            type is (integer)
               str = 'integer'
            type is (real(sp))
               str = 'real'
            class default
               str = 'whoops'
            end select
         rank (1)
            rnk = 1
            dims = [1,size(a)]
            select type(a)
            type is (integer)
               str = 'integer'
            type is (real(sp))
               str = 'real'
            class default
               str = 'whoops'
            end select
         rank default
            stop 'bad rank'
         end select

         print '(A,I0)',    'rank: ', rnk
         print '(A,*(I2))', 'dims: ', dims
         print '(A)',       'type: ' // str
         print *

      end subroutine bar

end program foo

If one now adds additional ranks to bar, the select type constructor is copied for each new rank.
The subroutine bar could be written in a much more concise manner if a polymorphic assumed-rank
entity were allowed as a selector in an select type construct. As far as I can tell, select type uses
only type and kind type parameters to determine the branch to take.

      subroutine bar(a)

         class(*), intent(in) :: a(..)
         integer rnk
         integer, allocatable :: dims(:)
         character(len=:), allocatable :: str

         select rank (a)
         rank (0)
            rnk = 0
            dims = [1,1]
         rank (1)
            rnk = 1
            dims = [1,size(a)]
         rank default
            stop 'bad rank'
         end select

         select type(a)
         type is (integer)
             str = 'integer'
         type is (real(sp))
            str = 'real'
         class default
            str = 'whoops'
         end select

         print '(A,I0)',    'rank: ', rnk
         print '(A,*(I2))', 'dims: ', dims
         print '(A)',       'type: ' // str
         print *

      end subroutine bar
@kargl
Copy link
Author

kargl commented Nov 2, 2024

Just discovered https://j3-fortran.org/doc/year/24/24-171.txt, which was passed at the recent J3 meeting. This document addresses this issue.

@kargl
Copy link
Author

kargl commented Nov 2, 2024

As a follow-up. J3 has also passed https://j3-fortran.org/doc/year/24/24-183r1.txt, which updates C840 to specifically allow an assumed-rank entity as a selector in a select type construct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant