Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
New Contributor II
94 Views

Recursive derived type compiler crash

Hello,

the code below causes the compiler to crash badly, while it presumably is legal Fortran.
I post this in case someone is interested or even wants to report this to Intel.

Description:

Type(X) recursively contains an allocatable type(X) component.
Using type(X) in a subprogram as intent(out) dummy argument, or as a function result (see example) causes a compiler crash.

Code:

module m
    implicit none
    type :: X
        type(X), allocatable :: a
    end type
contains
    type(X) function f
    end function
end module

Output:

$ ifort test.f90 -c
ifort: error #10105: /opt/intel/compilers_and_libraries_2019.3.199/linux/bin/intel64/fortcom: core dumped
ifort: warning #10102: unknown signal(-1269299024)
ifort: error #10106: Fatal error in /opt/intel/compilers_and_libraries_2019.3.199/linux/bin/intel64/fortcom, terminated by unknown
compilation aborted for test.f90 (code 1)

System Info:

  • Product Version: Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.3.199 Build 20190206
  • Host OS and Version: Ubuntu Description: Ubuntu 18.04.2 LTS Release: 18.04 Codename: bionic

Kind regards
Ferdinand

0 Kudos
3 Replies
Highlighted
Valued Contributor I
94 Views

Hi Ferdinand,

indeed this is legal Fortran, allocatable components of recursive type which is part of the F2008 standard. This is implemented in gfortran since 7.0, it is not (yet) implemented in the NAG compiler, and implemented in ifort since v18. v17 was still vetoing that code. All versions, however, show a segmentation fault when running the compiler. I'd read this as an uncaught internal compiler error (which is really, really rare). Please report this to the Intel support. The bug is still present in the v19.1 (pre-2020 release).

0 Kudos
Highlighted
Valued Contributor III
94 Views

Ferdinand T. wrote:

.. the code .. presumably is legal Fortran ..

While an ICE is always a compiler error and hopefully the issue has been reported and it will be fixed promptly by the vendor, the code does not appear to be standard-conforming,

  1. for one thing, the standard appears to require the parenthesis in the FUNCTION statement (see below, only the stuff with square brackets are optional) which are missing 
    25 15.6.2.2 Function subprogram
    26 1 A function subprogram is a subprogram that has a FUNCTION statement as its first statement.
    27 R1529 function-subprogram is function-stmt
    28 ..
    32 R1530 function-stmt is [ prefix ] FUNCTION function-name
    33 ( [ dummy-arg-name-list ] ) [ suffix ]

     

  2. The function result is not defined.  The standard states, "If the function result is not a pointer, its value shall be defined by the function"

Thankfully Intel Fortran compiles the following variant alright which is I believe is standard-conforming; just as for a reader of the code, it might be easier for the parser!

module m
   implicit none
   type :: X
      type(X), allocatable :: a
   end type
contains
   function f() result(r)
      type(X) :: r
      allocate( r%a )
   end function
end module

 

0 Kudos
Highlighted
New Contributor II
94 Views

@Juergen R.
I have now submitted a bug report through Intel support, I hope it won't be rejected this time. Thank you for the assessment!

@FortranFan
Very much appreciate you pointing to the actual Fortran standard details!

Concerning point 1. it appears that I was too greedy when writing the reproducer. However, adding the parentheses yields the same result (crash).

Regarding your point 2. though, if your conclusions were indeed correct that would forbid unallocated (ultimate) components in derived type function results. That seems to be too much of a restriction to me. Following your lead, I too have ventured into the standard and found the following:

16.6.1 Definition of objects and subobjects
[...]
4 A derived-type scalar object is defined if and only if all of its nonpointer components are defined

Hence, we must make sure the allocatable component '%a' of the function result is defined:

16.6.5 Events that cause variables to become defined
[...]
(25) Invocation of a nonpointer function of a derived type causes all nonpointer default-initialized sub-components of the function result to become defined

As I understand this, immedeately upon invokation, the allocatable component '%a' will become defined if it undergoes a default-initialization --- which it does:

4.5.4.6 Default initialization for components
1 [...] Allocatable components are always initialized to unallocated.

This brings me to the conclusion that the function result is indeed defined in my initial post.

I'd be happy to hear your thoughts on this 'derivation', I am not well versed in standard interpretation.

0 Kudos