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.
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.
module m implicit none type :: X type(X), allocatable :: a end type contains type(X) function f end function end module
$ 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)
- Product Version: Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.104.22.168 Build 20190206
- Host OS and Version: Ubuntu Description: Ubuntu 18.04.2 LTS Release: 18.04 Codename: bionic
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).
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,
- 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 22.214.171.124 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 ]
- 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
I have now submitted a bug report through Intel support, I hope it won't be rejected this time. Thank you for the assessment!
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 Deﬁnition of objects and subobjects [...] 4 A derived-type scalar object is deﬁned if and only if all of its nonpointer components are deﬁned
Hence, we must make sure the allocatable component '%a' of the function result is defined:
16.6.5 Events that cause variables to become deﬁned [...] (25) Invocation of a nonpointer function of a derived type causes all nonpointer default-initialized sub-components of the function result to become deﬁned
As I understand this, immedeately upon invokation, the allocatable component '%a' will become defined if it undergoes a default-initialization --- which it does:
126.96.36.199 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.