-
-
Save drikosev/a9e9e8357dbc45aeb02773198069222b to your computer and use it in GitHub Desktop.
! { dg-do run } | |
! { dg-shouldfail "Fortran runtime error: Assignment with unallocated RHS 'w'" } | |
! { dg-output "Fortran runtime error: Assignment with unallocated RHS 'w'" } | |
! Catch a Runtime error on intrinsic assignment of | |
! a class LHS with an unallocated RHS. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct0 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
class(d0), allocatable :: u | |
end type d2 | |
contains | |
subroutine destruct0(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct0 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d2), allocatable :: v | |
class(d1), allocatable :: w | |
type(d0), save :: allocatable1 = d0(1000) | |
type(d0), save :: allocatable2 = d0(2000) | |
print *, "Initializing..." | |
allocate ( v , source = d2(2,2,allocatable2)) | |
print *, "allocated v = d2(2,2,allocatable2=2000)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = w ( not allocated w )" | |
v = w | |
print *, "assined v = w, now v%ind=", v%ind, "allocated=", allocated(v) | |
print *, "-----------------" | |
print *, "exiting s() ..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= ?" | |
!if ( finalized /= ? ) error stop | |
end program test | |
! { dg-do run } | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct1 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
end type d2 | |
contains | |
subroutine destruct1(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct1 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d1), allocatable :: x | |
class(d2), allocatable :: y | |
class(d2), allocatable :: z | |
class(d2), allocatable :: v | |
type(d2), allocatable :: d | |
allocate(d); d%ind = 100 | |
allocate ( x , source = d1(1,1) ) | |
print *, "allocated x = d1(1,1)" | |
allocate ( y , source = d2(2,2)) | |
print *, "allocated y = d2(2,2)" | |
allocate ( z , source = d2(3,3)) | |
print *, "allocated z = d2(3,3)" | |
allocate ( v , source = d2(4,4)) | |
print *, "allocated v = d2(4,4)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = y (same class - shouldn't reallocate)" | |
v = y | |
print *, "assined v = y", " and now v%ind=", v%ind | |
print * | |
print *, "will assign v = v (shelf)" | |
v = v | |
print *, "assined v = v", " and now v%ind=", v%ind | |
print * | |
print *, "will assign v = d (same type - reallocation not implemented yet)" | |
v = d | |
print *, "assined v = d", " and now v%ind=", v%ind | |
print * | |
print *, "will assign v = x (other class)" | |
v = x | |
print *, "assined v = x", " and now v%ind=", v%ind | |
print * | |
print *, "-----------------" | |
print *, "Deallocating..." | |
if (allocated(x)) deallocate( x ) | |
if (allocated(y)) deallocate( y ) | |
if (allocated(z)) deallocate( z ) | |
if (allocated(v)) deallocate( v ) | |
print *, "-----------------" | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= 6" | |
if ( finalized /= 6 ) error stop | |
end program test | |
! { dg-do run } | |
! | |
! Check that the reallocation of a class(*) lhs works. | |
! Note that the functionality tested isn't for arrays. | |
module m | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: type_1 | |
integer ind | |
contains | |
final :: destruct1 | |
end type type_1 | |
type :: type_2 | |
integer ind | |
end type type_2 | |
type :: type_3 | |
integer ind,i | |
end type type_3 | |
contains | |
subroutine destruct1(self) | |
type(type_1), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "type_1 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1 | |
end if | |
end subroutine destruct1 | |
end module m | |
subroutine main() | |
use m | |
class(type_1), allocatable :: t1 | |
class(type_2), allocatable :: t2 | |
class(type_3), allocatable :: t3 | |
class(*), allocatable :: u | |
t1=type_1(1) | |
t2=type_2(2) | |
t3=type_3(3,3) | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
u=t1; if ( finalized /= 0 ) error stop 1; | |
u=t2; if ( finalized /= 1 ) error stop 2; | |
u=t3; if ( finalized /= 1 ) error stop 3; | |
print *, "exiting..." | |
end | |
program p | |
use m | |
call main() | |
print *, "finalized=", finalized, ", expected= 2" | |
if ( finalized /= 2 ) error stop | |
end | |
! { dg-do run } | |
! | |
! Check that the reallocation of a class(*) lhs works. | |
! Note that the functionality tested isn't for arrays. | |
module m | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: type_1 | |
integer ind | |
contains | |
final :: destruct1 | |
end type type_1 | |
type :: type_2 | |
integer ind | |
end type type_2 | |
type :: type_3 | |
integer ind,i | |
end type type_3 | |
contains | |
subroutine destruct1(self) | |
type(type_1), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "type_1 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1 | |
end if | |
end subroutine destruct1 | |
end module m | |
subroutine main() | |
use m | |
class(type_1), allocatable :: t1 | |
class(type_2), allocatable :: t2 | |
class(type_3), allocatable :: t3 | |
class(*), allocatable :: u | |
t1=type_1(1) | |
t2=type_2(2) | |
t3=type_3(3,3) | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
! Check any bug that may execute the finalizer of the RHS. | |
u=t2; if ( finalized /= 0 ) error stop 1; | |
u=t1; if ( finalized /= 0 ) error stop 2; | |
u=t3; if ( finalized /= 1 ) error stop 3; | |
print *, "exiting..." | |
end | |
program p | |
use m | |
call main() | |
print *, "finalized=", finalized, ", expected= 2" | |
if ( finalized /= 2 ) error stop | |
end | |
! { dg-do run } | |
! Test reallocation of a scalar LHS when RHS is a derived. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct1 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
end type d2 | |
contains | |
subroutine destruct1(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct1 | |
end module testmode | |
subroutine s2 | |
use testmode | |
implicit none | |
class(d1), allocatable :: x | |
class(d2), allocatable :: y | |
class(d2), allocatable :: z | |
class(d0), allocatable :: v | |
type(d2), allocatable :: d | |
allocate ( x , source = d1(1,1)) | |
print *, "allocated x = d1(1,1)" | |
allocate ( d , source = d2(2,2)) | |
print *, "allocated d = d2(2,2)" | |
allocate ( v , source = d2(4,4)) | |
print *, "allocated v = d2(4,4)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = d (same type)" | |
v = d | |
print *, "assined v = d, and now v%ind=", v%ind | |
print * | |
print *, "will assign v = x (other type)" | |
v = x | |
print *, "assined v = x, and now v%ind=", v%ind | |
print * | |
print *, "-----------------" | |
print *, "exiting s2() ..." | |
end subroutine s2 | |
program test | |
use testmode | |
implicit none | |
call s2() | |
print *, "finalized=", finalized, ", expected= 4" | |
if ( finalized /= 4 ) error stop | |
end program test | |
! { dg-do run } | |
! Test reallocation of a scalar LHS when RHS is a derived | |
! of the same type but with different attributes (pointer). | |
! Just in case, as they have different vtab at compile time | |
! and the patch for PR/64290 compares the vptr at runtime. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct1 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
end type d2 | |
contains | |
subroutine destruct1(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct1 | |
end module testmode | |
subroutine s2 | |
use testmode | |
implicit none | |
class(d1), allocatable :: x | |
class(d2), allocatable :: y | |
class(d2), allocatable :: z | |
class(d0), allocatable :: v | |
type(d2), pointer :: d | |
allocate ( x , source = d1(1,1)) | |
print *, "allocated x = d1(1,1)" | |
allocate ( d , source = d2(2,2)) | |
print *, "allocated d = d2(2,2)" | |
allocate ( v , source = d2(4,4)) | |
print *, "allocated v = d2(4,4)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = d (same type)" | |
v = d | |
print *, "assined v = d, and now v%ind=", v%ind | |
print * | |
print *, "will assign v = x (other type)" | |
v = x | |
print *, "assined v = x, and now v%ind=", v%ind | |
print * | |
print *, "-----------------" | |
print *, "exiting s2() ..." | |
!we explicitly deallocate the pointer object | |
deallocate(d) | |
end subroutine s2 | |
program test | |
use testmode | |
implicit none | |
call s2() | |
print *, "finalized=", finalized, ", expected= 4" | |
if ( finalized /= 4 ) error stop | |
end program test | |
! { dg-do run } | |
! | |
! Test intrinsic assignments when the RHS is either a member of | |
! the LHS or a type-bound procedure (of the LHS). In specific | |
! two kinds of down-casting are tested here: | |
! | |
! v = v%downcast() | |
! x = x%base | |
module testmode | |
implicit none | |
integer, public, save :: finalized_d0 = 0 | |
integer, public, save :: finalized_d2 = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
type (d0), pointer :: base => null() | |
integer :: id | |
contains | |
final :: destruct_d0 | |
procedure :: downcast => downcast0 | |
end type d0 | |
type, extends(d0) :: d2 | |
integer no | |
contains | |
final :: destruct_d2 | |
procedure :: downcast => downcast2 | |
end type d2 | |
interface d0 | |
module procedure construct_d0 | |
end interface | |
interface d2 | |
module procedure construct_d2 | |
end interface | |
contains | |
function construct_d0( id ) result(r) | |
integer, intent(in) :: id | |
type(d0) :: r | |
r%id = id | |
end function | |
function construct_d2( id, no ) result(r) | |
integer, intent(in) :: id, no | |
type(d2) :: r | |
r%id = id | |
r%no = no | |
end function | |
subroutine destruct_d0(this) | |
implicit none | |
type(d0), intent(inout) :: this | |
if ( counting > 0 ) then | |
print *, "finalizing ... (d0), id=", this%id | |
finalized_d0 = finalized_d0 + 1; | |
end if | |
end subroutine destruct_d0 | |
subroutine destruct_d2(this) | |
implicit none | |
type(d2), intent(inout) :: this | |
if ( counting > 0 ) then | |
print *, "finalizing ... (d2), id=", this%id, "no=", this%no | |
finalized_d2 = finalized_d2 + 1; | |
end if | |
end subroutine destruct_d2 | |
function downcast0(this) result (b) | |
implicit none | |
class(d0), intent(inout) :: this | |
type(d0) :: b | |
if ( .not. associated(this%base)) this%base = this | |
b = this%base | |
end function downcast0 | |
function downcast2(this) result (b) | |
implicit none | |
class(d2), intent(inout) :: this | |
type(d0) :: b | |
b = downcast0(this) | |
end function downcast2 | |
end module testmode | |
subroutine s() | |
use testmode | |
implicit none | |
class(d0), target, allocatable :: v | |
class(d0), target, allocatable :: x | |
allocate( v, source = d2(2,2)) | |
print * | |
print *, "allocated v = d2(2,2)" | |
v%base => v | |
print *, "assigned v%base =>v" | |
allocate( x, source = d2(3,3)) | |
print * | |
print *, "allocated x = d2(3,3)" | |
x%base => x | |
print *, "assigned x%base =>x" | |
! Reset this as we test only intrinsic assignments | |
finalized_d0 = 0 | |
finalized_d2 = 0 | |
counting = 1 | |
print *, "set finalized_d0=0, finalized_d2=0" | |
print * | |
print * | |
print *, "will downcast v to d0 ( v = v%downcast() )" | |
print *, "-------- before -------" | |
select type (v) | |
class is (d0) | |
print *, "runtime type: (d0), id=", v%id, "sizeof(v)=", sizeof(v) | |
class is (d2) | |
print *, "runtime type: (d2), id=", v%id, "sizeof(v)=", sizeof(v) | |
end select | |
print *, "downcasting ..." | |
v = v%downcast() | |
print *, "-------- after --------" | |
select type (v) | |
class is (d0) | |
print *, "runtime type: (d0), id=", v%id, "sizeof(v)=", sizeof(v) | |
class is (d2) | |
print *, "runtime type: (d2), id=", v%id, "sizeof(v)=", sizeof(v) | |
end select | |
if ( finalized_d2 /= 1 ) error stop 1 | |
if ( finalized_d0 /= 1 ) error stop 2 | |
print * | |
print *, "will downcast x to d0 ( x = x%base )" | |
print *, "-------- before -------" | |
select type (x) | |
class is (d0) | |
print *, "runtime type: (d0), id=", x%id, "sizeof(x)=", sizeof(x) | |
class is (d2) | |
print *, "runtime type: (d2), id=", x%id, "sizeof(x)=", sizeof(x) | |
end select | |
print *, "downcasting ..." | |
x = x%base | |
print *, "-------- after --------" | |
select type (x) | |
class is (d0) | |
print *, "runtime type: (d0), id=", x%id, "sizeof(x)=", sizeof(x) | |
class is (d2) | |
print *, "runtime type: (d2), id=", x%id, "sizeof(x)=", sizeof(x) | |
end select | |
if ( finalized_d2 /= 2 ) error stop 3 | |
if ( finalized_d0 /= 2 ) error stop 4 | |
print *, "-----------------" | |
print *, "exiting s()..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "-------- TOTALS ---------" | |
print *, "finalized_d2=", finalized_d2, ", expected= 2" | |
print *, "finalized_d0=", finalized_d0, ", expected= 4" | |
if ( finalized_d2 /= 2 ) error stop 5 | |
if ( finalized_d0 /= 4 ) error stop 6 | |
end program test | |
macbook:gcc-4.8.5 suser$ gfc -g gcc/testsuite/gfortran.dg/realloc_final_5.f90 && ./a.out | |
allocated v = d2(2,2) | |
assigned v%base =>v | |
allocated x = d2(3,3) | |
assigned x%base =>x | |
will downcast v to d0 ( v = v%downcast() ) | |
-------- before ------- | |
runtime type: (d2), id= 2 sizeof(v)= 24 | |
downcasting ... | |
finalizing ... (d2), id= 2 no= 2 | |
finalizing ... (d0), id= 2 | |
-------- after -------- | |
runtime type: (d0), id= 2 sizeof(v)= 16 | |
will downcast x to d0 ( x = x%base ) | |
-------- before ------- | |
runtime type: (d2), id= 3 sizeof(x)= 24 | |
downcasting ... | |
finalizing ... (d2), id= 3 no= 3 | |
finalizing ... (d0), id= 3 | |
Program received signal SIGSEGV: Segmentation fault - invalid memory reference. | |
Backtrace for this error: | |
#0 0x10be73509 | |
#1 0x10be73d2e | |
#2 0x7fff5dffbb5c | |
#3 0x10be67d8d | |
#4 0x10be690b9 | |
#5 0x10be6959b | |
#6 0x10be69798 | |
Segmentation fault: 11 | |
macbook:gcc-4.8.5 suser$ |
macbook:gcc-4.8.5 suser$ gfc -g gcc/testsuite/gfortran.dg/realloc_class_5.f90 && ./a.out | |
allocated v = d2(2,2) | |
assigned v%base =>v | |
allocated x = d2(3,3) | |
assigned x%base =>x | |
set finalized_d0=0, finalized_d2=0 | |
will downcast v to d0 ( v = v%downcast() ) | |
-------- before ------- | |
runtime type: (d2), id= 2 sizeof(v)= 24 | |
downcasting ... | |
finalizing ... (d2), id= 2 no= 2 | |
finalizing ... (d0), id= 2 | |
-------- after -------- | |
runtime type: (d0), id= 2 sizeof(v)= 16 | |
will downcast x to d0 ( x = x%base ) | |
-------- before ------- | |
runtime type: (d2), id= 3 sizeof(x)= 24 | |
downcasting ... | |
finalizing ... (d2), id= 3 no= 3 | |
finalizing ... (d0), id= 3 | |
-------- after -------- | |
runtime type: (d0), id= 3 sizeof(x)= 16 | |
----------------- | |
exiting s()... | |
finalizing ... (d0), id= 3 | |
finalizing ... (d0), id= 2 | |
-------- TOTALS --------- | |
finalized_d2= 2 , expected= 2 | |
finalized_d0= 4 , expected= 4 | |
macbook:gcc-4.8.5 suser$ |
! { dg-do run } | |
! Test reallocation of a scalar LHS with an allocatable | |
! component. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct0 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
class(d0), allocatable :: u | |
end type d2 | |
contains | |
subroutine destruct0(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct0 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d1), allocatable :: x | |
class(d0), allocatable :: v | |
type(d0), save :: allocatable = d0(1000) | |
print *, "Initializing..." | |
allocate ( x , source = d1(1,1)) | |
print *, "allocated x = d1(1,1)" | |
allocate ( v , source = d2(2,2,allocatable)) | |
print *, "allocated v = d2(2,2,allocatable=1000)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = x (other class)" | |
v = x | |
print *, "assined v = x, now v%ind=", v%ind | |
print * | |
print *, "-----------------" | |
print *, "exiting s() ..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= 4" | |
if ( finalized /= 4 ) error stop | |
end program test | |
! { dg-do run } | |
! Test reallocation of a scalar LHS with allocatable | |
! components, larger than 16 bytes, in the base class. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: T | |
character(20) :: ch | |
end type T | |
type :: d0 | |
integer :: ind | |
integer, allocatable :: a | |
type(T), allocatable :: b | |
contains | |
final :: destruct0 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i = 1 | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j = 2 | |
end type d2 | |
contains | |
subroutine destruct0(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct0 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d1), allocatable :: x | |
class(d0), allocatable :: v | |
integer, allocatable :: m,n | |
print *, "Initializing..." | |
allocate ( m , source = 101) | |
print *, "allocated m = 101" | |
allocate ( n , source = 102) | |
print *, "allocated n = 102" | |
allocate ( x ) | |
x%ind = 1 | |
x%a = m | |
x%b = T("_______________Hello") | |
x%i = 1 | |
print *, "allocated x = d1(1,m,1)" | |
allocate ( v ) | |
v%ind = 2 | |
v%a = n | |
v%b = T("_______________World") | |
print *, "allocated v = d0(2,n)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "before: v = , now v%ind=", v%ind, " and v%a=", v%a, v%b%ch | |
print * | |
print *, "will assign v = x (other class)" | |
v = x | |
print * | |
print *, "after: v = , now v%ind=", v%ind, " and v%a=", v%a, v%b%ch | |
if ( v%a /= m ) error stop 1 | |
if ( trim(v%b%ch) /= "_______________Hello" ) error stop 2 | |
print *, "-----------------" | |
print *, "exiting s() ..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= 3" | |
if ( finalized /= 3 ) error stop | |
end program test | |
! { dg-do run } | |
! Test reallocation of an unlimited polymorphic scalar | |
! LHS with an allocatable component. | |
! | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct0 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
class(d0), allocatable :: u | |
end type d2 | |
contains | |
subroutine destruct0(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct0 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d1), allocatable :: x | |
class(*), allocatable :: v | |
type(d0), save :: allocatable = d0(1000) | |
print *, "Initializing..." | |
allocate ( x , source = d1(1,1)) | |
print *, "allocated x = d1(1,1)" | |
allocate ( v , source = d2(2,2,allocatable)) | |
print *, "allocated v = d2(2,2,allocatable=1000)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = x (other class)" | |
v = x | |
select type (v) | |
class is (d1) | |
print *, "assined v = x, now v%ind=", v%ind | |
class default | |
error stop 1 | |
end select | |
print * | |
print *, "-----------------" | |
print *, "exiting s() ..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= 4" | |
if ( finalized /= 4 ) error stop 2 | |
end program test | |
! { dg-do run } | |
! Test intrinsic assignment of a scalar LHS with | |
! an allocatable component that doesn't reallocate. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct0 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
class(d0), allocatable :: u | |
end type d2 | |
contains | |
subroutine destruct0(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct0 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d2), allocatable :: x | |
class(d2), allocatable :: v | |
type(d0), save :: allocatable1 = d0(1000) | |
type(d0), save :: allocatable2 = d0(2000) | |
print *, "Initializing..." | |
allocate ( x , source = d2(1,1,allocatable1)) | |
print *, "allocated x = d2(1,1,allocatable1=1000)" | |
allocate ( v , source = d2(2,2,allocatable2)) | |
print *, "allocated v = d2(2,2,allocatable2=2000)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = x (same class - different components)" | |
v = x | |
print *, "assined v = x, now v%ind=", v%ind | |
print * | |
print *, "-----------------" | |
print *, "exiting s() ..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= 4" | |
if ( finalized /= 4 ) error stop | |
end program test | |
! { dg-do run } | |
! | |
! Test reallocation as demonstrated in F2018, 10.2.1.3 | |
! for deferred chars with subroutine DEFERRED_LENGTH | |
! | |
! Also test the case that the NAME has a fixed length | |
! with subroutine FIXED_LENGTH | |
SUBROUTINE DEFERRED_LENGTH() | |
CLASS(*), ALLOCATABLE :: USER | |
CHARACTER(:),ALLOCATABLE :: NAME | |
CHARACTER(:),ALLOCATABLE :: FIRST_NAME | |
CHARACTER(:),ALLOCATABLE :: SURNAME | |
USER = 'NONE' | |
NAME = 'NONE' | |
PRINT * | |
PRINT *, "DEFERRED LENGTH NAME" | |
! Print Values & Compare | |
PRINT * | |
PRINT *, "NAME=", NAME, " [LEN=", LEN(NAME), "]" | |
SELECT TYPE (USER) | |
TYPE IS (CHARACTER(*)) | |
PRINT *, "USER=", USER, " [LEN=", LEN(USER), "]" | |
IF ( LEN(USER) /= LEN(NAME) ) STOP 1 | |
IF ( LEN(USER) /= 4 ) STOP 2 | |
IF ( USER /= NAME ) STOP 3 | |
END SELECT | |
ALLOCATE( FIRST_NAME , SOURCE = 'John Richard' ) | |
ALLOCATE( SURNAME , SOURCE = 'Doe' ) | |
USER = 'Mr. '//FIRST_NAME//' '//SURNAME | |
NAME = 'Mr. '//FIRST_NAME//' '//SURNAME | |
! Print Values & Compare | |
PRINT * | |
PRINT *, "NAME=", NAME, " [LEN=", LEN(NAME), "]" | |
SELECT TYPE (USER) | |
TYPE IS (CHARACTER(*)) | |
PRINT *, "USER=", USER, " [LEN=", LEN(USER), "]" | |
IF ( LEN(USER) /= LEN(NAME) ) STOP 4 | |
IF ( LEN(USER) /= 20 ) STOP 5 | |
IF ( USER /= NAME ) STOP 6 | |
END SELECT | |
USER = SURNAME | |
NAME = SURNAME | |
! Print Values & Compare | |
PRINT * | |
PRINT *, "NAME=", NAME, " [LEN=", LEN(NAME), "]" | |
SELECT TYPE (USER) | |
TYPE IS (CHARACTER(*)) | |
PRINT *, "USER=", USER, " [LEN=", LEN(USER), "]" | |
IF ( LEN(USER) /= LEN(NAME) ) STOP 7 | |
IF ( LEN(USER) /= 3 ) STOP 8 | |
IF ( USER /= NAME ) STOP 9 | |
END SELECT | |
END SUBROUTINE DEFERRED_LENGTH | |
SUBROUTINE FIXED_LENGTH() | |
CLASS(*), ALLOCATABLE :: USER | |
CHARACTER(15),ALLOCATABLE :: NAME | |
CHARACTER(:), ALLOCATABLE :: FIRST_NAME | |
CHARACTER(:), ALLOCATABLE :: SURNAME | |
PRINT * | |
PRINT *, "FIXED LENGTH NAME" | |
NAME = 'NONE' | |
USER = NAME | |
! Print Values & Compare | |
PRINT * | |
PRINT *, "NAME=", NAME, " [LEN=", LEN(NAME), "]" | |
SELECT TYPE (USER) | |
TYPE IS (CHARACTER(*)) | |
PRINT *, "USER=", USER, " [LEN=", LEN(USER), "]" | |
IF ( LEN(USER) /= LEN(NAME) ) STOP 11 | |
IF ( LEN(USER) /= 15 ) STOP 12 | |
IF ( USER /= NAME ) STOP 13 | |
END SELECT | |
ALLOCATE( FIRST_NAME , SOURCE = 'John Richard' ) | |
ALLOCATE( SURNAME , SOURCE = 'Roe' ) | |
NAME = 'Mr. '//FIRST_NAME//' '//SURNAME | |
USER = NAME | |
! Print Values & Compare | |
PRINT * | |
PRINT *, "NAME=", NAME, " [LEN=", LEN(NAME), "]" | |
SELECT TYPE (USER) | |
TYPE IS (CHARACTER(*)) | |
PRINT *, "USER=", USER, " [LEN=", LEN(USER), "]" | |
IF ( LEN(USER) /= LEN(NAME) ) STOP 14 | |
IF ( LEN(USER) /= 15 ) STOP 15 | |
IF ( USER /= NAME ) STOP 16 | |
END SELECT | |
NAME = SURNAME | |
USER = NAME | |
! Print Values & Compare | |
PRINT * | |
PRINT *, "NAME=", NAME, " [LEN=", LEN(NAME), "]" | |
SELECT TYPE (USER) | |
TYPE IS (CHARACTER(*)) | |
PRINT *, "USER=", USER, " [LEN=", LEN(USER), "]" | |
IF ( LEN(USER) /= LEN(NAME) ) STOP 17 | |
IF ( LEN(USER) /= 15 ) STOP 18 | |
IF ( USER /= NAME ) STOP 19 | |
END SELECT | |
END SUBROUTINE FIXED_LENGTH | |
CALL DEFERRED_LENGTH() | |
CALL FIXED_LENGTH() | |
PRINT * | |
END | |
! { dg-do run } | |
! Test intrinsic assignment of a scalar LHS with | |
! an allocatable component that doesn't reallocate, | |
! because it's not polymorphic. | |
module testmode | |
implicit none | |
integer, public, save :: finalized = 0 | |
integer, public, save :: counting = 0 | |
type :: d0 | |
integer :: ind | |
contains | |
final :: destruct0 | |
end type d0 | |
type, extends(d0) :: d1 | |
integer :: i | |
end type d1 | |
type, extends(d0) :: d2 | |
integer :: j | |
class(d0), allocatable :: u | |
end type d2 | |
contains | |
subroutine destruct0(self) | |
type(d0), intent(inout) :: self | |
if ( counting > 0 ) then | |
print *, "d0 % destruct1(self): ind=", self%ind | |
finalized = finalized + 1; | |
end if | |
end subroutine destruct0 | |
end module testmode | |
subroutine s | |
use testmode | |
implicit none | |
class(d2), allocatable :: x | |
type(d2), allocatable :: v,w | |
type(d0), save :: allocatable1 = d0(1000) | |
type(d0), save :: allocatable2 = d0(2000) | |
print *, "Initializing..." | |
allocate ( x , source = d2(1,1,allocatable1)) | |
print *, "allocated x = d2(1,1,allocatable1=1000)" | |
allocate ( v , source = d2(2,2,allocatable2)) | |
print *, "allocated v = d2(2,2,allocatable2=2000)" | |
allocate ( w , source = d2(3,3,allocatable2)) | |
print *, "allocated w = d2(3,3,allocatable2=3000)" | |
! Reset this as we test only intrinsic assignments | |
finalized = 0 | |
counting = 1 | |
print *, "set finalized=0" | |
print * | |
print *, "-----------------" | |
print *, "will assign v = x (same class - different components)" | |
v = x | |
print *, "assined v = x, now v%ind=", v%ind, "allocated=", allocated(v) | |
print * | |
print *, "will assign v = w (same type - non poly assignment)" | |
v = w | |
print *, "assined v = w, now v%ind=", v%ind, "allocated=", allocated(v) | |
print *, "-----------------" | |
print *, "exiting s() ..." | |
end subroutine s | |
program test | |
use testmode | |
implicit none | |
call s() | |
print *, "finalized=", finalized, ", expected= 6" | |
if ( finalized /= 6 ) error stop | |
end program test | |
[Files Renamed]
I'd like to figure out what these two programs should print:
realloc_class_8.f90
realloc_class_9.f90
Also, I'd like to figure out if all examples are valid Fortran programs.
The example realloc_class_6.f90 is perhaps invalid. Just in case, I'll change this:
class(d2), allocatable :: v
to:
class(d0), allocatable :: v
Also changed:
class(d2), allocatable :: v
to
class(d0), allocatable :: v
in realloc_class_4.f90 &
realloc_class_4.f95
Having some feedback, fixed the expected result (was '?') in:
realloc_class_8.f90 [expected=4]
realloc_class_9.f90 [expected=6]
One may test any example from realloc_class_1.f90 to realloc_class_8.f95
As the example realloc_class_0.f90 attempts to catch a runtime error, so
testing it with a compiler other than my gfortran-4.8.5 may be pointless.
The example realloc_class_9.f90 has a non polymorphic assignment that
turned to be out of scope at the moment, where gfortran makes a
deallocation, invalid as I was informed.
I'd like to figure out what these two programs should print:
realloc_final_8.f90
realloc_final_9.f90
Also, I'd like to figure if all examples are valid Fortran programs.