Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26739 Discussions

Catastrophic error / ICE when using class(*) with type

mRabbel
Beginner
135 Views

Hi there,

 

I'm experimenting with polymorphism and when writing a module for managing dynamic lists, I sometimes got an ICE, sometimes it worked. I discovered that when using class(*) on type structures, it somehow requires the presence of at least one allocatable array.

MWE:

module testclass
  type tClass
    class(*), pointer :: X
  contains
    procedure :: getX,setX
  end type
contains
  function getX(this)
    class(*),pointer :: getX
    class(tClass) :: this
    getX => this%X
  end function

  subroutine setX(this,x)
    class(*) :: x
    class(tClass) :: this
    allocate(this%X,source=x)
  end subroutine
end module

program bugtest
use testclass

type :: tTest
  integer :: A
  ! uncommenting 'dummy' resolves the ICE
  !integer, allocatable,dimension(:) :: dummy
end type

type(tClass) :: myClass
type(tTest)  :: myA

myA .A = 42
call myClass.setX(myA)
myA .A = 43

myA = myClass.getX()
print *, myA.A

end program

 

ifort -O1 does work, O2 and O3 gives an ICE.

Alternatively, uncommenting "dummy" compiles fine for O2 and O3 as well.

 

Tested on:

ifort Version 19.0.4.243 Build 20190416

openSUSE Leap 15.1

AMD Opteron 2376, Intel Xeon E5620 (tested on both).

 

Kind regards,

MR

0 Kudos
2 Replies
Steve_Lionel
Black Belt Retired Employee
126 Views

Reproducible in 19.1.3 and the OneAPI Beta. Please report this through the Online Service Center.

FortranFan
Honored Contributor II
119 Views

@mRabbel ,

As advised upthread, please report the ICE to Intel if you are able to.

But please do note

  1. the use of unlimited polymorphic types (CLASS(*) and also TYPE(*) which is more toward interoperation with C) are fraught,
  2. Moreover, there are severe gaps when it comes to GENERICS in Fortran and an attempt to employ unlimited polymorphism to overcome the limitations with generics in Fortran can be an exercise in futility.
  3. Additionally, there are other limitations in Fortran when it comes to lack of adequate support in the language standard itself with certain aspects of OO in the form of no required copy elision, no move semantics, etc. and given the typical issues with pointers of dangling ones and memory leaks, extreme care is needed to achieve functioning OO 'classes' using pointer components. 
  4. There is no easy facility for 'casting' in Fortran and you'll need to use the more verbose SELECT TYPE construct to consume your OO 'classes' unless you expend further effort to study OO patterns to avoid such needs.
  5. Finally, you'll need to be always mindful of the "=>" syntax with pointer assignments in the language.

To overcome the first point above and thus making it easy on a compiler and help it overcome an ICE, you can consider a 'base' Class, a "homebrew" of a superobject the way Java does it.  See a modified example below which also addresses a few of the above issues.

module baseClass
   type, abstract :: b_t
   end type
end module

module testclass
   use baseClass, only : b_t
   type :: tClass
      class(b_t), pointer :: X
   contains
      procedure, pass(this) :: getX, setX
   end type
contains
   function getX(this)
      class(b_t), pointer :: getX
      class(tClass), intent(in) :: this
      getX => this%X
   end function

   subroutine setX(this, x)
      class(b_t), intent(in) :: x
      class(tClass), intent(inout) :: this
      allocate(this%X, source=x)
   end subroutine
end module

program bugtest
   use baseClass, only : b_t
   use testclass

   type, extends(b_t) :: tTest
      integer :: A = 0
   end type

   type(tClass) :: myClass
   type(tTest)  :: myA
   class(b_t), pointer  :: myB

   myA%A = 42
   call myClass%setX( myA )
   myA%A = 43

   myB => myClass%getX()  !<-- Note this
   select type ( B => myB )  !<-- mimic casting
      type is ( tTest )
         print *, "myB%A = ", B%A, "; expected is 42"
      class default
         ! flag error?
   end select

end program

Upon execution,

C:\temp>ifort /standard-semantics /stand:f18 /warn:all p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1 Beta Build 20200827
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.27.29112.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\temp>p.exe
 myB%A =  42 ; expected is 42

C:\temp>

 

Reply