Skip to content

Instantly share code, notes, and snippets.

@alanbriolat
Created October 2, 2013 13:09
Show Gist options
  • Save alanbriolat/6793476 to your computer and use it in GitHub Desktop.
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.
! 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