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

Internal compiler error - default initialization for nested derived types with arrays

Vincent4
Beginner
626 Views

Hi,

With the following code, ifort crashes with an internal compiler error:

module object_module
  implicit none

  type :: object_inner
    integer :: tag = -1
  end type

  type :: object
    type(object_inner), dimension(2) :: inner = object_inner()
  contains
    procedure, pass, public :: get
  end type object

contains

  function get(this) result(num)
    implicit none
    class(object), intent(in) :: this
    integer :: num
    num = 0
  end function get

end module object_module

!--------------------------
! User module
module object_user
  use object_module
  implicit none

  type :: user
      !type(object) :: g = object(object_inner()) ! OK for both compilers
      type(object) :: g = object()               ! crashes ifort
  contains
    procedure, pass :: generate_crash
  end type user

contains

  subroutine generate_crash(this)
    implicit none
    class(user), intent(in) :: this
    integer :: dummy
    dummy = this % g % get()
  end subroutine generate_crash

end module object_user
!--------------------------

When trying to compile:

> ifort --version
ifort (IFORT) 2021.4.0 20210910
Copyright (C) 1985-2021 Intel Corporation.  All rights reserved.

> ifort -c ifort_crash.F90
ifort_crash.F90(44): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report.  Note: File and line given may not be explicit cause of this error.
compilation aborted for ifort_crash.F90 (code 1)

 Line 32 of the code sample indicates a possible workaround, but that is not feasible if we want to keep "object_inner" private within the module. Is this even valid Fortran code?

Let me know if this is not the right place to report such an error.

Thanks

Labels (2)
0 Kudos
1 Solution
Devorah_H_Intel
Moderator
563 Views

Thank you for reporting this bug. I have escalated this to our compiler development for a fix. No, need to do anything else about this report. 

View solution in original post

5 Replies
FortranFan
Honored Contributor II
595 Views

@Vincent4 ,

As you may know, an internal compiler error can be considered a compiler bug and as such, a compiler developer shall be keen to have it reported immediately in order to get the issue resolved.

If you have support subscription, please submit a request at Intel OSC: https://supporttickets.intel.com/servicecenter?lang=en-US

Otherwise, you can hope Intel staff will pick up the incident from here.

FortranFan
Honored Contributor II
590 Views

@Vincent4 ,

Not sure whether it will work with your actual code, but for the code you show in the original post, you don't need to default initialize the components of your derived types "object" and "user".  The ultimate component of both of these derived types end up being "tag" in your type "object_inner".  And "tag" is initialized.  Under the circumstances, the following is something you can consider:

module object_module
  implicit none

  type :: object_inner
    integer :: tag = -1
  end type

  type :: object
    type(object_inner), dimension(2) :: inner !<-- inner%tag initialized
  contains
    procedure, pass, public :: get
  end type object

contains

  function get(this) result(num)
    implicit none
    class(object), intent(in) :: this
    integer :: num
    num = 0
  end function get

end module object_module

!--------------------------
! User module
module object_user
  use object_module
  implicit none

  type :: user
      type(object) :: g !<-- g%inner%tag initialized
  contains
    procedure, pass :: generate_crash
  end type user

contains

  subroutine generate_crash(this)
    implicit none
    class(user), intent(in) :: this
    integer :: dummy
    dummy = this % g % get()
  end subroutine generate_crash

end module object_user
Vincent4
Beginner
567 Views

Thank you for the suggestion @FortranFan . Unfortunately. I need to initialize objects of type "user" from a pointer to uninitialized memory given by an external routine. Without the explicit default initialization of each component, code such as

u = user()

results in a compilation error with

ifort_crash.F90(51): error #8212: Omitted component is not initialized. Component initialization missing:   [G]
      u = user()

 Is there another way to initialize objects that I am unaware of? I'm wondering whether it's necessary to define a custom constructor for "user" and "object" (which is another way to work around this compilation issue).

FortranFan
Honored Contributor II
527 Views

 

@Vincent4 writes:
.. Without the explicit default initialization of each component, code such as

u = user()
results in a compilation error with

ifort_crash.F90(51): error #8212: Omitted component is not initialized. Component initialization missing:   [G]
      u = user()
 Is there another way to initialize objects that I am unaware of? I'm wondering whether it's necessary to define a custom constructor for "user" and "object" (which is another way to work around this compilation issue).

 

@Vincent4 ,

Depending on how your "classes" (derived types in Fortran parlance) are designed, a "class" instance (usually just a variable in Fortran) does not need to "instantiated" with a constructor in order for its class "members" to have default values.  Type definition (and allocation in the case of variables with ALLOCATABLE attribute) does that for you.  Thus you do not need "u = user()" statements.  With the code I show upthread, "type(user) :: u" in a program unit will have "u" defined.  For example,

 

   use object_user
   type(user) :: u
   print *, "u%g%inner%tag = ", u%g%inner%tag, "; expected is -1 -1"
end
C:\Temp>ifort /standard-semantics a.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.3.0 Build 20210609_000000
Copyright (C) 1985-2021 Intel Corporation.  All rights reserved.

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

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

C:\Temp>a.exe
 u%g%inner%tag =  -1 -1 ; expected is -1 -1

 

 

But then if you somehow have a need to perform an assignment operation "u = user()" to "construct" your "class" instance of "u", you can consider a "custom" constructor.  Current Fortran standard allows a generic interface to have the same name as that of the derived type, so you can make use of that facility if that would help.  For example,

 

module object_user
  use object_module
  implicit none

  type :: user
      type(object) :: g !<-- g%inner%tag initialized
  contains
    procedure, pass :: generate_crash
  end type user

  generic :: user => construct_user  !<-- generic interface with same name

contains

  function construct_user( tag ) result(r)
     integer, intent(in), optional :: tag
     type(user) :: r
     if ( present(tag) ) r%g%inner%tag = tag
  end function 

  subroutine generate_crash(this)
    implicit none
    class(user), intent(in) :: this
    integer :: dummy
    dummy = this % g % get()
  end subroutine generate_crash

end module object_user
   use object_user
   type(user) :: u
   u = user( tag=42 ) !<-- retry with tag omitted.
   print *, "u%g%inner%tag = ", u%g%inner%tag, "; expected is 42 42"
end
C:\Temp>ifort /standard-semantics a.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.3.0 Build 20210609_000000
Copyright (C) 1985-2021 Intel Corporation.  All rights reserved.

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

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

C:\Temp>a.exe
 u%g%inner%tag =  42 42 ; expected is 42 42

 

Devorah_H_Intel
Moderator
564 Views

Thank you for reporting this bug. I have escalated this to our compiler development for a fix. No, need to do anything else about this report. 

Reply