Created
October 2, 2013 13:09
-
-
Save alanbriolat/6793476 to your computer and use it in GitHub Desktop.
A demonstration of a weird cross-module array-inside-derived-type initialisation bug in ifort.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! A demonstration of a weird cross-module array-inside-derived-type | |
! initialisation bug in ifort. ifort --version: ifort (IFORT) 14.0.0 20130728. | |
! None of these issues appear in other compilers tested (gfortran 4.6 and 4.7). | |
module module_a | |
implicit none | |
private | |
integer :: i | |
! Test the array initialiser, works just fine. | |
real, dimension(5), parameter :: test_array = (/(0, i = 1, 5)/) | |
! A derived type containing an array with an implied-DO initialiser. Some of | |
! the valid forms of initialisation each have strange compiler behaviour. | |
type, public :: A | |
! [1] Compiler segfault if A() is used outside of this module. | |
real, dimension(5) :: foo = (/(0, i = 1, 5)/) | |
!real, dimension(5) :: foo = (/(0.0, i = 1, 5)/) | |
! [2] Works correctly. | |
!real, dimension(5) :: foo = (/(0*i, i = 1, 5)/) | |
!real, dimension(5) :: foo = (/(0.0*i, i = 1, 5)/) | |
! [3] 'error #6595: The shape of an element in a structure constructor | |
! differs from the shape of the component of the derived type' if A() is | |
! used outside of this module. | |
!real, dimension(5) :: foo = (/1, (0, i = 2, 5)/) | |
!real, dimension(5) :: foo = (/1.0, (0.0, i = 2, 5)/) | |
! [4] Works correctly. | |
!real, dimension(5) :: foo = (/1, (0*i, i = 2, 5)/) | |
!real, dimension(5) :: foo = (/1.0, (0.0*i, i = 2, 5)/) | |
end type A | |
! Check if A's constructor is considered a valid constant expression | |
type(A), parameter :: default_a = A() ! Always works | |
! A derived type that makes use of A's constructor - this should only work if | |
! A() is considered a valid constant expression | |
type, public :: B | |
type(A) :: my_a = A() ! Always works | |
end type B | |
! Check if B's constructor is considered a valid constant expression | |
type(B), parameter :: default_b = B() ! Always works | |
contains | |
end module module_a | |
module module_b | |
use module_a | |
implicit none | |
private | |
! Derived type just like B, but in a different module | |
type, public :: C | |
type(A) :: my_a = A() ! Segfault with [1], error with [3] | |
end type C | |
! Check if initialisation expressions work here | |
type(A), parameter :: another_a = A() ! Segfault with [1], error with [3] | |
type(B), parameter :: another_b = B() | |
type(C), parameter :: default_c = C() ! Segfault with [1], error with [3] | |
contains | |
end module module_b |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment