- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following test program exhibits what I think is not clearly allowed for forbidden by the standard but works on any compiler but the Intel versions I tried (14.0.2, 15.0.0):
PROGRAM ifort_ptr_dealloc REAL, POINTER :: p(:, :, :), q(:, :) ALLOCATE(p(5,6,1)) p = 1.0 q => p(:, :, 1) DEALLOCATE(q) END PROGRAM ifort_ptr_dealloc
Compiling and running results in an abort:
$ ifort -o ifort-ptr-dealloc ifort-ptr-dealloc.f90 $ ../ifort-ptr-dealloc forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated Image PC Routine Line Source ifort-ptr-dealloc 00000000004081B2 Unknown Unknown Unknown ifort-ptr-dealloc 0000000000402E95 Unknown Unknown Unknown ifort-ptr-dealloc 0000000000402CAE Unknown Unknown Unknown libc.so.6 00007F9C579F2CAD Unknown Unknown Unknown ifort-ptr-dealloc 0000000000402BB9 Unknown Unknown Unknown
Since most other compilers tried (pgfortran 14.7, nagfor 5.3.2(990), gfortran 4.8.2) happen to work I hope this can be resolved. Except for xlf 13.1.0.8 and 14.1.0.8, where AIX 6.1 running on POWER6 was used and the program was also aborted, all tests were made on Intel Xeon E5-2665 CPU running 64bit Linux.
Regards, Thomas
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I submitted a (Low) enhancement request to Development (see internal tracking id below) for consideration and will update the thread with details of what I hear regarding it.
(Internal tracking id: DPD200239656)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>Since most other compilers tried (pgfortran 14.7, nagfor 5.3.2(990), gfortran 4.8.2) happen to work I hope this can be resolved.
???
I think you mean happen to fail to report an error.
P was allocated, Q was not.
Consider:
PROGRAM ifort_ptr_dealloc REAL, POINTER :: p(:, :, :), q(:, :) ALLOCATE(p(5,6,7)) ! *** NOTE 7 p = 1.0 q => p(:, :, 1) ! A slice of P not whole of P DEALLOCATE(q) END PROGRAM ifort_ptr_dealloc
What do you expect to happen? From your statement regarding (pgfortran 14.7, nagfor 5.3.2(990), gfortran 4.8.2) I suppose you would expect only the slice of P to be deallocated.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may be that the standard permits the "slice identical to whole" to be deletable.
I do not know the internals of Fortran to know if internally the allocations internally have a reference count, and/or a list of references.
If so, then in the original example, the deallocate(q) would also have to disassociate p (and all other pointers). This could be implemented by use of an allocation object, containing something like a void* and a reference count. And the pointers containing an array descriptor and a reference to the allocation object.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It appears that the pointer q is associated with a rank-2 slice of the rank-3 array p, so while the extent of the third dimension of p happens to be 1, I don't think that q can be considered equivalent to the whole of p.
If you add a statement
print *, associated (p)
after the deallocate statement, you'll see that gfortran and NAG print a "T", which I think is fine.
If I compile with "ifort -check all -g ifort_ptr_dealloc.f90 -traceback", I get:
forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated
Image PC Routine Line Source
a.out 08059984 Unknown Unknown Unknown
a.out 0804A66A MAIN__ 6 ifort_ptr_dealloc.f90
a.out 08049FD6 Unknown Unknown Unknown
which I think is also fine, as the deallocate invokes undefined behaviour, as you already mentioned.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If the slice is the whole array, the standard says you should be able to deallocate it. I thought I reported this some time ago but can't find the issue right now, so it's good that Kevin did so,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Harald wrote:
It appears that the pointer q is associated with a rank-2 slice of the rank-3 array p, so while the extent of the third dimension of p happens to be 1, I don't think that q can be considered equivalent to the whole of p.
If you add a statement
print *, associated (p)
after the deallocate statement, you'll see that gfortran and NAG print a "T", which I think is fine.
Only fine in the sense that if you read the wording of the standard and see that the status of p becomes undefined (under the assumption that it's actually defined behaviour to deallocate q), calling associated for p already invokes undefined behaviour.
Harald wrote:
If I compile with "ifort -check all -g ifort_ptr_dealloc.f90 -traceback", I get:
forrtl: severe (173): A pointer passed to DEALLOCATE points to an object that cannot be deallocated
Image PC Routine Line Source
a.out 08059984 Unknown Unknown Unknown
a.out 0804A66A MAIN__ 6 ifort_ptr_dealloc.f90
a.out 08049FD6 Unknown Unknown Unknownwhich I think is also fine, as the deallocate invokes undefined behaviour, as you already mentioned.
The question if this is indeed UB is the whole point of my initial post.
Regards, Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
>>Since most other compilers tried (pgfortran 14.7, nagfor 5.3.2(990), gfortran 4.8.2) happen to work I hope this can be resolved.
???
I think you mean happen to fail to report an error.
P was allocated, Q was not.
Since neither P nor Q are ALLOCATABLEs they are only associated to the same object. Depending on the interpretation whether Q is associated with the "whole" of the object ALLOCATEd via P or not, calling DEALLOCATE for Q is fine, and P becomes undefined subsequently, i.e. cannot be used until nullified or otherwise associated again, or deallocating q is invalid as ifort seems to believe.
jimdempseyatthecove wrote:
Consider:
PROGRAM ifort_ptr_dealloc REAL, POINTER :: p(:, :, :), q(:, :) ALLOCATE(p(5,6,7)) ! *** NOTE 7 p = 1.0 q => p(:, :, 1) ! A slice of P not whole of P DEALLOCATE(q) END PROGRAM ifort_ptr_deallocWhat do you expect to happen? From your statement regarding (pgfortran 14.7, nagfor 5.3.2(990), gfortran 4.8.2) I suppose you would expect only the slice of P to be deallocated.
Since the "slice" Q references all of P, it remains to clarify whether that is sufficiently close to "whole" as the standard puts it.
Regards, Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
It may be that the standard permits the "slice identical to whole" to be deletable.
Which is the reason I posted in the first place.
jimdempseyatthecove wrote:
I do not know the internals of Fortran to know if internally the allocations internally have a reference count, and/or a list of references.
If so, then in the original example, the deallocate(q) would also have to disassociate p (and all other pointers). This could be implemented by use of an allocation object, containing something like a void* and a reference count. And the pointers containing an array descriptor and a reference to the allocation object.
Fortran implementations have many freedoms how to implement this internally, but the behaviour you sketch is not permitted: if the deallocate is successful the association status of p becomes undefined and cannot be used without invoking undefined behaviour, especially not for another deallocate. This is not Objective C or Java.
Regards, Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Although p becomes undefined, my feelings are it would be convenient to either:
a) disassociate the additional pointer(s) thus causing runtime error (permitted as undefined behavior)
b) leave the additional pointer(s) associated but pointed at location 0 thus causing runtime error (permitted as undefined behavior).
This would permit the programmer to catch early a hidden bug. Yes it adds a tad of overhead. So possibly have a diagnostic option to enforce this behavior.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I updated the internal tracking id in my earlier reply with the id of an earlier reported instance of the defect reported in this thread and which will track any associated fix in a future release. I will update this thread as I learn more.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page