- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"Dead code elimination" is an optimization that is not relevant here. I am looking into this further.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My sincere thanks to both of you for your explanations and feedback!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This problem has been fixed for a release later this year.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page