STORAGE_SIZE does not work for unallocated polymorphic types. However, the Fortran 2008 standard allows them: "A shall be a scalar or array of any type. If it is polymorphic it shall not be an undefined pointer. If it has any deferred type parameters it shall not be an unallocated allocatable variable or a disassociated or undefined pointer." (F2008, 13.7.160) Note: The standard allows an unallocated polymorphic variable - as long as the type does not have any deferred type parameter. Fortunately, CLASS(*) does not seem to be allowed as "CLASS(*)" has no type. Maybe one should cross check (e.g. at the J3 mailing list) to see whether the proper result is the declared type or something else. implicit none type t integer :: a end type t type, extends(t) :: t2 integer :: b end type t2 class(t), allocatable :: y print *, storage_size(y)/8 ! Expected: "4"; in reality: segfault end
IR 10-171 (http://j3-fortran.org/doc/year/10/10-171.txt) adds the text in the bracket (which does not apply here): "If it [is unlimited polymorphic or] has any deferred type parameters it shall not be ..." * * * I have now asked at J3: http://j3-fortran.org/pipermail/j3/2010-December/004090.html
(In reply to comment #0) > STORAGE_SIZE does not work for unallocated polymorphic types. However, the > Fortran 2008 standard allows them: > > "A shall be a scalar or array of any type. If it is polymorphic it shall not > be an undefined pointer. If it has any deferred type parameters it shall > not be an unallocated allocatable variable or a disassociated or > undefined > pointer." (F2008, 13.7.160) I don't really understand this. Why should one allow it for unallocated allocatables, but not for undefined pointers? Also, it's not exactly clear to me which value to expect for such a case. From the standard's description of STORAGE_SIZE: "The result value is the size expressed in bits for an element of an array that has the dynamic type and type parameters of A." However, if A is unallocated, it does not have a dynamic type!
(In reply to comment #2) > I don't really understand this. Why should one allow it for unallocated > allocatables, but not for undefined pointers? Well, the situation for an unassociated pointer and for an unallocated allocatable is the same: You know that it does not have a dynamic type -- and you can check for this state via "<array>.data == NULL" or "<scalar> == NULL". In case of an undefined pointer, you cannot. Thus, not allowing undefined pointers anywhere makes sense. The initially proposed wording was did not allow for notallocated allocatables/notassociated pointers (http://www.j3-fortran.org/doc/year/06/06-166.txt) but during the meeting 176 meeting the wording of 06-166 was changed (in two revisions, r1 and r2) to what we have today; cf. http://www.j3-fortran.org/doc/meeting/176/06-166r2.txt. Unfortunately, the new version does not clearly tell what the result value should be in that case. Possible choices would be: (a) storage size of the declared type or (b) "zero" or the size of the class container. If (b) is the correct answer, I do not see the reason for the additional restrictions for types with "deferred type parameters" and for "unlimited polymorphic" - one could simply return the same as for an unallocated polymorphic. Thus, I assume that (a) is meant, but I do not see how one can read this from the standard (as opposed to guessing it). Let's see what the J3 members think how it should be interpreted; I think ultimately an interpretation request is required.
(In reply to comment #2) > However, if A is unallocated, it does not have a dynamic type! According to Bill Long's interpretation at http://j3-fortran.org/pipermail/j3/2010-December/004094.html the dynamic type of an unallocated variable is it's dynamic type.
The dump for the test case in comment #0 currently looks like this [excerpt]: y._data = 0B; { [...] _gfortran_st_write (&dt_parm.0); { integer(kind=4) D.1548; D.1548 = (y._vptr->_size * 8) / 8; _gfortran_transfer_integer_write (&dt_parm.0, &D.1548, 4); } _gfortran_st_write_done (&dt_parm.0); } Since "y._vptr" is initially undefined, we get an ICE. The solution would be to initialize the _vptr component of all polymorphic allocatables to the declared type.
Mine. Have a patch.
Author: janus Date: Wed Jan 5 09:05:44 2011 New Revision: 168505 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168505 Log: 2011-01-05 Janus Weil <janus@gcc.gnu.org> PR fortran/47024 * trans-decl.c (gfc_trans_deferred_vars): Initialize the _vpr component of polymorphic allocatables according to their declared type. 2011-01-05 Janus Weil <janus@gcc.gnu.org> PR fortran/47024 * gfortran.dg/storage_size_3.f08: New. Added: trunk/gcc/testsuite/gfortran.dg/storage_size_3.f08 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-decl.c trunk/gcc/testsuite/ChangeLog
Fixed with r168505. Closing.