Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28630 Discussions

Potential Bug when using Assumed Rank with Unlimited Polymorphic

Lamb__Tripp
New Contributor I
370 Views

There must be something I'm misunderstanding.

I'm attempting to use an assumed rank unlimited polymorphic variable to store data. When I do this I either get access violations or corrupted data. I built a little toy problem to showcase the issue (listed below). The first is an access violation and the second is the corrupted data.

Access Violation

   real, target :: x
   class(*), pointer :: x_ptr

   x = 5.6
   x_ptr => x
   call do_stuff(x_ptr)

contains

   subroutine do_stuff(item)

       class(*), dimension(..), intent(in) :: item

       select rank(item)
       rank(0)
           select type(item) !<--- this is where the debugger crashes
           type is (real)
               print *, item
           end select
       end select

   end subroutine do_stuff

Corrupted Data

   real, target :: x
   class(*), pointer :: x_ptr

   x = 5.6
   x_ptr => x
   call do_stuff(x_ptr)

contains

   subroutine do_stuff(item)

       class(*), dimension(..), intent(in) :: item

       select rank(item)
       rank(0)
           call do_stuff_inner(item)
       end select

   end subroutine do_stuff

   subroutine do_stuff_inner(item)

       class(*), intent(in) :: item

       select type(item)
       type is (real)
           print *, item ! prints 4.735692598010119E-312
       end select

   end subroutine do_stuff_inner

I appreciate any explanation of what I'm doing wrong. I'm using intel fortran oneapi 2023.0.0.25839. Also to test for posting it does work on this compiler https://www.onlinegdb.com/online_fortran_compiler

0 Kudos
1 Solution
andrew_4619
Honored Contributor III
239 Views
program test
real, target :: x
class(*), pointer :: x_ptr
x = 5.6
x_ptr => x
call do_stuff(x_ptr)
call do_stuff2(x_ptr)
print *, 'Finished'
contains
subroutine do_stuff(item)
    class(*), dimension(..), intent(in) :: item
    select rank(item)
    rank(0)
        select type(item) !<--- this is where the debugger crashes
        type is (real)
            print *, item
        end select
    end select
end subroutine do_stuff
subroutine do_stuff2(item)
    class(*), dimension(..), intent(in) :: item
    select rank(item)
    rank(0)
        call do_stuff_inner(item)
    end select
end subroutine do_stuff2
subroutine do_stuff_inner(item)
    class(*), intent(in) :: item
    select type(item)
    type is (real)
        print *, item ! prints 4.735692598010119E-312
    end select
end subroutine do_stuff_inner
end program test

And putting both example in 2024.2 that work also with output 5.6, 5.6, Finished. I suggest you update.

View solution in original post

4 Replies
FortranFan
Honored Contributor III
340 Views

@Lamb__Tripp ,

Try using the latest Intel opeAPI processor v2024.2, perhaps the issue is fixed already?

Also, a variant you can try is where you use the associate-name facility in the Fortran standard to make it easier for the processor and anyone else reading the code to understand which object is what.  See below, perhaps that might help avoid the issue?

Ultimately, you may want to post a reproducer that illustrates the issue with the proper code and the steps you took that led to the problems.

   real, target :: x
   class(*), pointer :: x_ptr

   x = 5.6
   x_ptr => x
   call do_stuff(x_ptr)

contains

   subroutine do_stuff( arg )

       class(*), dimension(..), intent(in) :: arg

       select rank( item => arg ) !<-- here 'item' effectively becomes an object of specific rank, not one that is an assumed rank
          rank( 0 )
             select type( val => item ) !<-- here 'val' effectively becomes an object of specific type and kind, not polymorphic
                type is (real)
                   print *, val
             end select
       end select

   end subroutine

end
0 Kudos
Lamb__Tripp
New Contributor I
253 Views

The associate-name method did not change any behavior. I'll give updating to 2024 a go. It's just a pain as the code is on a computer not connected to the internet, or I would have already tried that.

I'm not sure what a reproducer is, or at least how it differs from what I already posted.

0 Kudos
andrew_4619
Honored Contributor III
240 Views
program test
real, target :: x
class(*), pointer :: x_ptr
x = 5.6
x_ptr => x
call do_stuff(x_ptr)
contains
subroutine do_stuff(item)
    class(*), dimension(..), intent(in) :: item
    select rank(item)
    rank(0)
        select type(item) !<--- this is where the debugger crashes
        type is (real)
            print *, item
        end select
    end select
end subroutine do_stuff
end program test

With Intel® Fortran Compiler 2024.2.0 [Intel(R) 64] that program ran OK in debug

andrew_4619
Honored Contributor III
240 Views
program test
real, target :: x
class(*), pointer :: x_ptr
x = 5.6
x_ptr => x
call do_stuff(x_ptr)
call do_stuff2(x_ptr)
print *, 'Finished'
contains
subroutine do_stuff(item)
    class(*), dimension(..), intent(in) :: item
    select rank(item)
    rank(0)
        select type(item) !<--- this is where the debugger crashes
        type is (real)
            print *, item
        end select
    end select
end subroutine do_stuff
subroutine do_stuff2(item)
    class(*), dimension(..), intent(in) :: item
    select rank(item)
    rank(0)
        call do_stuff_inner(item)
    end select
end subroutine do_stuff2
subroutine do_stuff_inner(item)
    class(*), intent(in) :: item
    select type(item)
    type is (real)
        print *, item ! prints 4.735692598010119E-312
    end select
end subroutine do_stuff_inner
end program test

And putting both example in 2024.2 that work also with output 5.6, 5.6, Finished. I suggest you update.

Reply