Bug 47024 - [OOP] STORAGE_SIZE (for polymorphic types): Segfault at run time
Summary: [OOP] STORAGE_SIZE (for polymorphic types): Segfault at run time
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2010-12-20 09:35 UTC by Tobias Burnus
Modified: 2011-01-05 09:17 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-04 13:39:10


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2010-12-20 09:35:17 UTC
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
Comment 1 Tobias Burnus 2010-12-20 09:47:11 UTC
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
Comment 2 janus 2010-12-20 15:16:44 UTC
(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!
Comment 3 Tobias Burnus 2010-12-20 16:47:56 UTC
(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.
Comment 4 janus 2011-01-04 13:39:10 UTC
(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.
Comment 5 janus 2011-01-04 13:49:27 UTC
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.
Comment 6 janus 2011-01-04 18:58:30 UTC
Mine. Have a patch.
Comment 7 janus 2011-01-05 09:05:48 UTC
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
Comment 8 janus 2011-01-05 09:17:25 UTC
Fixed with r168505. Closing.