! { dg-do run } ! { dg-options "-fdump-tree-original" } ! ! Tests the fixes for three bugs with the same underlying cause. All are regressions ! that come about because class array elements end up with a different tree type ! to the class array. In addition, the language specific flag that marks a class ! container is not being set. ! ! PR53876 contributed by Prince Ogunbade ! PR54990 contributed by Janus Weil ! PR54992 contributed by Tobias Burnus ! The two latter bugs were reported by Andrew Benson ! starting at http://gcc.gnu.org/ml/fortran/2012-10/msg00087.html ! module G_Nodes type :: nc type(tn), pointer :: hostNode end type nc type, extends(nc) :: ncBh end type ncBh type, public, extends(ncBh) :: ncBhStd double precision :: massSeedData end type ncBhStd type, public :: tn class (ncBh), allocatable, dimension(:) :: cBh end type tn type(ncBhStd) :: defaultBhC contains subroutine Node_C_Bh_Move(targetNode) implicit none type (tn ), intent(inout) , target :: targetNode class(ncBh), allocatable , dimension(:) :: instancesTemporary ! These two lines resulted in the wrong result: allocate(instancesTemporary(2),source=defaultBhC) call Move_Alloc(instancesTemporary,targetNode%cBh) ! These two lines gave the correct result: !!deallocate(targetNode%cBh) !!allocate(targetNode%cBh(2)) targetNode%cBh(1)%hostNode => targetNode targetNode%cBh(2)%hostNode => targetNode return end subroutine Node_C_Bh_Move function bhGet(self,instance) implicit none class (ncBh), pointer :: bhGet class (tn ), intent(inout), target :: self integer , intent(in ) :: instance bhGet => self%cBh(instance) return end function bhGet end module G_Nodes call pr53876 call pr54990 call pr54992 end subroutine pr53876 IMPLICIT NONE TYPE :: individual integer :: icomp ! Add an extra component to test offset REAL, DIMENSION(:), ALLOCATABLE :: genes END TYPE CLASS(individual), DIMENSION(:), ALLOCATABLE :: indv allocate (indv(2), source = [individual(1, [99,999]), & individual(2, [999,9999])]) CALL display_indv(indv(2)) ! Similarly, reference 2nd element to test offset CONTAINS SUBROUTINE display_indv(self) CLASS(individual), INTENT(IN) :: self if (any(self%genes .ne. [999,9999]) )call abort END SUBROUTINE END subroutine pr54990 implicit none type :: ncBhStd integer :: i end type type, extends(ncBhStd) :: ncBhStde integer :: i2(2) end type type :: tn integer :: i ! Add an extra component to test offset class (ncBhStd), allocatable, dimension(:) :: cBh end type integer :: i type(tn), target :: a allocate (a%cBh(2), source = [(ncBhStde(i*99, [1,2]), i = 1,2)]) select type (q => a%cBh(2)) ! Similarly, reference 2nd element to test offset type is (ncBhStd) call abort type is (ncBhStde) if (q%i .ne. 198) call abort ! This tests that the component really gets the end select ! language specific flag denoting a class type end subroutine pr54992 ! This test remains as the original. use G_Nodes implicit none type (tn), target :: b class(ncBh), pointer :: bh class(ncBh), allocatable, dimension(:) :: t allocate(b%cBh(1),source=defaultBhC) b%cBh(1)%hostNode => b ! #1 this worked if (loc(b) .ne. loc(b%cBh(1)%hostNode)) call abort call Node_C_Bh_Move(b) ! #2 this worked if (loc(b) .ne. loc(b%cBh(1)%hostNode)) call abort if (loc(b) .ne. loc(b%cBh(2)%hostNode)) call abort ! #3 this did not bh => bhGet(b,instance=1) if (loc (b) .ne. loc(bh%hostNode)) call abort bh => bhGet(b,instance=2) if (loc (b) .ne. loc(bh%hostNode)) call abort end ! { dg-final { scan-tree-dump-times "builtin_free" 12 "original" } } ! { dg-final { cleanup-tree-dump "original" } }