Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29280 Discussions

Deallocation fails - Hard to explain case ( if + class )

kostas85
Beginner
782 Views

Dear All,

I have noticed the following strange behaviour. In the following example, I define a class component of a type, named alpha_set, and this type is a component of another type, beta_set. I also define two arrays of type beta_set. The command in the main program:

    if (allocated(bset2)) deallocate(bset1) 

or the class declaration of alpha_set:

    class(alpha), dimension(:), allocatable :: member
   
causes the final deallocation statement to fail with error 153 (allocatable array or component is not allocated - version  13.1.0.146). 

I am not sure if this is an expected behaviour. Please let me know what you think. Many thanks.

Here is the code: 

[fortran] module mini_type

implicit none

type alpha
real :: hi
end type alpha

type alpha_set
class(alpha), dimension(:), allocatable :: member ! <- if class changes to type, runs properly
end type alpha_set

type beta_set
type(alpha_set), dimension(:), allocatable :: member
end type beta_set

type(beta_set), dimension(:), allocatable, target :: bset1, bset2


end module mini_type

program test_mini

use mini_type

integer :: i

allocate(bset1(10))

if (allocated(bset2)) deallocate(bset1) ! <-- if commented runs properly

do i=1,size(bset1),3

allocate(bset1(i)%member(3))

end do

do i=1,size(bset1)

if (allocated(bset1(i)%member)) then

deallocate(bset1(i)%member)

end if

end do

end program test_mini [/fortran]


 

0 Kudos
9 Replies
jimdempseyatthecove
Honored Contributor III
782 Views

As an experiment, remove ", bset2" from the declaration that creates bset1, change allocated(bset2) to allocated(bset1)

Compile with same options and run.

Your original code should have run without error, but if the test succeeds, then this may be indicative of an error in dead code elimination (code manipulating and producing unused results elimination). This may help the support people in isolating the problem.

Jim Dempsey

0 Kudos
kostas85
Beginner
782 Views

Hi Jim,

The changes you proposed create the following code that also doesn't run and terminates with the same error as before. I forgot to mention that code fails when it deallocates bset1(i)%member. Could you please explain dead code elimination a bit more for this case ?  Thank you for your suggestion.

Kostas
 

[fortran]  

module mini_type

implicit none

type alpha
real :: hi
end type alpha

type alpha_set
class(alpha), dimension(:), allocatable :: member ! <- if class changes to type, runs properly
end type alpha_set

type beta_set
type(alpha_set), dimension(:), allocatable :: member
end type beta_set

type(beta_set), dimension(:), allocatable, target :: bset1!, bset2  <-- change 1 : removed bset2 from declaration statement


end module mini_type

program test_mini

use mini_type

integer :: i

if (allocated(bset1)) deallocate(bset1) ! <-- change 2 : bset2 is now bset1, also moved the statement before the allocation of bset1

allocate(bset1(10))


do i=1,size(bset1),3

allocate(bset1(i)%member(3))

end do

do i=1,size(bset1)

if (allocated(bset1(i)%member)) then

deallocate(bset1(i)%member)

end if

end do


end program test_mini [/fortran]

0 Kudos
Steven_L_Intel1
Employee
782 Views

"Dead code elimination" is an optimization that is not relevant here. I am looking into this further.

0 Kudos
Steven_L_Intel1
Employee
782 Views

I believe that the compiler is not properly initializing the state of the alpha_set arrays. I have escalated this as issue DPD200241489 and will let you know of any progress.

0 Kudos
jimdempseyatthecove
Honored Contributor III
782 Views

Dead code elimination:

When the compiler can determine when a code branch is never taken, thus never be excuited, the compiler removes the code from the object file. This code was called dead code. The compiler writers then saw, that when the results of a computation are not used, then why not remove the code that performs those calculations (call those statement dead code).

In your original code, you had an array that was allocated and never used. Other than for the execution statement of an if test that could be determined as to never being executed (IOW as dead code). Dead code of that IF test and .true. statement never to be execuited, then removed the only reference to an array was allocate. I was making a supposition that the compiler may have removed the allocation as well.

Supposition continues to by removing the allocation that the declaration for that array could also me removed (such that the array descriptor need not be initialized). My supposition (and area for exploration) is the "unused" array descriptor was not cleanly removed and thus an error was exposed. This is all guess work on my part.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
782 Views

It is true that removing the reference to bset2 causes bset2 itself to be completely removed from the code. Why this has an effect on the error, I don't yet know. The compiler did not do dead code elimination, as either the code was there (and was executed), or not there in the first place.

0 Kudos
kostas85
Beginner
782 Views

My sincere thanks to both of you for your explanations and feedback!

0 Kudos
jimdempseyatthecove
Honored Contributor III
782 Views

>>It is true that removing the reference to bset2 causes bset2 itself to be completely removed from the code.

My supposition was that the constructor for the bset2 array descriptor was removed as part of the dead code elimination process, however the uninitialized array descriptor was left around. Then on exit from scope, the auto deallocate of allocatables used the uninitialized array descriptor. That is one theory. The other theory is the token for the bset2 array descriptor was not removed and the compiler confused the token for bset1 with token for bset2 thus referencing an uninitialized array descriptor or referencing a compile time allocated object (C/C++ object allocated for compilation purposes), that was subsiquently deleted/freed.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
782 Views

This problem has been fixed for a release later this year.

0 Kudos
Reply