program test_bug_openmp
!$ use omp_lib
implicit none

type :: parentClass
  real :: a
end type 

type, extends(parentClass) :: childClass
  real :: b 
end type

type :: my_struct
  class(parentClass), pointer :: var ! Bug 1 : internal compiler error if declared allocatable instead and declared PRIVATE in parralel OMP section. Fix: declared as pointer or as FIRSTPRIVATE
end type

type(my_struct) :: polyVar 

print*, "Start program"

!$OMP PARALLEL FIRSTPRIVATE(polyVar) 
print*, OMP_GET_THREAD_NUM()+1, "/", OMP_GET_NUM_THREADS(), "Threads"

! Bug #2 : segmentation fault during allocation if my_struct%var is declared allocatable and declared FIRSTPRIVATE. Fix: use pointer declaration instead of allocatable
allocate(childClass :: polyVar%var) 

! Bug #3 : segmentation fault due to associated name in select type. Does not work either with an explicitly declared pointer 'ptr'. Fix: call a subroutine

select type (ptr => polyVar%var)
type is (parentClass)
  ptr%a = 1.0
  print*, "Parent :", ptr%a
type is (childClass)
  ptr%a = 1.0
  ptr%b = 2.0
  print*, "Child :", ptr%a, ptr%b
end select

!call sub(polyVar)

!$OMP END PARALLEL

print*, "End program"

contains

subroutine sub(my_polyvar)
type(my_struct) :: my_polyvar

select type (ptr => my_polyvar%var)
type is (parentClass)
  ptr%a = 1.0
  print*, "Parent :", ptr%a
type is (childClass)
  ptr%a = 1.0
  ptr%b = 2.0
  print*, "Child :", ptr%a, ptr%b
end select

end subroutine sub

end program test_bug_openmp
