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

Segmentation fault due to assignment of derived-type variable from module

jlentz
Novice
1,352 Views

Hello,

 

I am encountering a segmentation fault in code compiled with either ifx 2023.1.0 or with ifort 2021.9.0. I've attached an example program which triggers the segfault.

 

In words, the segfault occurs when a subroutine in a program assigns a local copy of a derived-type module variable. It only seems to occur when the derived type contains an allocatable member, and it only occurs when the program contains an earlier use of the same module variable.

 

Any help with this would be appreciated.

11 Replies
FortranFan
Honored Contributor II
1,314 Views

@jlentz ,

You may want to post the exact error message or a screenshot of the program response and either submit via a support request at Intel Service Center if you had paid for the service, or hope that someone from the Intel team will pick it up from this thread.

But otherwise, know the code you attach does NOT conform to the language, as shown there can be a reference to an undefined object - the component `my_member` of the derived type, during the assignment instruction.  You can take suitable action to avoid such a reference as that is the programmer's responsibility per the language.  One option you can try to understand is as shown below, see if the "crash" you notice is avoided with this change:

module my_module
  implicit none

  type my_type
    integer,allocatable :: my_member(:)
  end type

  type(my_type) :: my_var
end module

program my_test

  use my_module
  implicit none
  call crash()

contains

  ! The subroutine below is never called and it therefore does nothing. But the
  ! segfault only occurs if it is present.
  subroutine this_subroutine_is_never_called
    type(my_type) :: my_copy
    my_copy = my_var
  end subroutine

  subroutine crash
    type(my_type) :: my_copy
    if ( allocated(my_var%my_member) ) then 
       my_copy = my_var
    end if
  end subroutine

end program
0 Kudos
IanH
Honored Contributor II
1,238 Views

The code is conforming. The rules for intrinsic assignment (e.g. F2018 10.2.1.3p13) and the rules for what conceptually constitutes the value of an object of derived type (F2018 7.5.8) (versus the value of a reference to the component of an object derived type) are consistent and clear on what happens. The work-around should not be required - this is just a compiler bug (the error message is just nonsensical).

An intrinsic assignment statement where the variable is of derived type is performed as if.... For a non-coarray allocatable component, the following sequence of operations is applied.

1) If the component of the variable is allocated, it is deallocated.

2) If the component of the value of expr is allocated...

 

0 Kudos
FortranFan
Honored Contributor II
1,211 Views

@IanH wrote:

The code is conforming. ..


NO, it's not.  There is a fair amount of semantics in the language and its standard that comes into play with the code in the original post before that with the intrinsic assignment,.

The standard is clear "A reference is permitted only if the variable is defined" and that "A derived-type scalar object is defined if and only if all of its nonpointer components are defined." 

Basically the reference to "my_var" in the instruction "my_copy = my_var" does not conform, "my_var" is not defined as shown.

0 Kudos
IanH
Honored Contributor II
1,181 Views

The standard specifies the component value of an unallocated allocatable component in terms of its allocation status (F2018 7.5.8p1).  This is used to specify the value that an object of derived type with unallocated components has (7.5.8p2).  The standard specifies the initial allocation status of such a component (7.5.4.6p1).  The standard provides for default initialization (which is the mechanism under which the initial allocation status of an allocatable component is specified) to initially define objects.

The my_var variable of the module my_module is defined.  The reference to it, in the assignment statements in the subroutines of the OP, is permitted. 

(Those assignment statements do not reference the value of the component - they reference the allocation status of the component, as per the rules that specify the value of an object of derived type.  As it has been, ever since the allocatable TR...)

 

0 Kudos
jlentz
Novice
1,124 Views

Reading this discussion was instructive, thank you.

0 Kudos
Ron_Green
Moderator
1,279 Views

I may still write up a bug report on this example. While non-conformant, I would want a better error message that the one shown below.  Interestingly, gfortran runs this without complaint at all!  But as we know, if you write non-comformant code then the implementations may have unpredictable behaviors.  Still, I think our runtime error message is misleading.  That, and the fact that you need the 'never_called' to get the runtime fault has me thinking there is something wrong in how ifx and ifort are parsing this code.

 

 

ifx -g -traceback -O0 -o example example.F90
rwgreen@orcsle153:~/quad$ ./example
forrtl: severe (189): LHS and RHS of an assignment statement have incompatible types
Image              PC                Routine            Line        Source             
example            0000000000408F0F  Unknown               Unknown  Unknown
example            00000000004056A0  crash                      28  example.F90
example            000000000040520C  my_test                    15  example.F90
example            00000000004051CD  Unknown               Unknown  Unknown
libc.so.6          00007FA869829510  Unknown               Unknown  Unknown
libc.so.6          00007FA8698295C9  __libc_start_main     Unknown  Unknown
example            00000000004050E5  Unknown               Unknown  Unknown

 

0 Kudos
Steve_Lionel
Honored Contributor III
1,267 Views

FWIW, NAG Fortran, even with maximum checking, compiles and runs example.f90 without complaint.

0 Kudos
FortranFan
Honored Contributor II
1,155 Views

@Steve_Lionel wrote:

FWIW, NAG Fortran, even with maximum checking, compiles and runs example.f90 without complaint.


Considering the standard - as considerate as it tries to be for the interests of processors as much as or more than the practitioners, it will not be surprising if NAG Fortran runs the following nonconforming program without complaint, notwithstanding any pedantic mode it might take on during compile-time:

   j = i
end

 

0 Kudos
jlentz
Novice
1,263 Views

Thank you all for your replies. Two points that I'd like to add:

 

1) The issue still occurs when `my_var%my_member` is allocated prior to calling `crash`. For example, the following code also crashes:

 

module my_module
  implicit none

  type my_type
    integer,allocatable :: my_member(:)
  end type

  type(my_type) :: my_var
end module

program my_test

  use my_module
  implicit none
  allocate(my_var%my_member(0))
  call crash

contains

  ! The subroutine below is never called and it therefore does nothing. But the
  ! segfault only occurs if it is present.
  subroutine this_subroutine_is_never_called
    type(my_type) :: my_copy
    my_copy = my_var
  end subroutine

  subroutine crash
    type(my_type) :: my_copy
    my_copy = my_var
  end subroutine

end program

 

2) For the minimal example shown here, when compiled with either ifx or ifort, the error posted by @Ron_Green is shown:

forrtl: severe (189): LHS and RHS of an assignment statement have incompatible types

But in the context of our actual code base (in which I discovered this issue), we see a segmentation fault rather than that error message:

forrtl: severe (174): SIGSEGV, segmentation fault occurred

I've been unable to discover the exact boundary between the conditions that lead to the "LHS and RHS..." message and to the segmentation fault.

0 Kudos
Ron_Green
Moderator
1,255 Views

We use the same Fortran Runtime Library (FRTL) for ifx and ifort. It's shared, just one frtl.


I am pretty sure there is a parsing error. The bug ID is CMPLRLLVM-48120


0 Kudos
Ron_Green
Moderator
711 Views

this bug is fixed in the 2024.0 release.


0 Kudos
Reply