Patch to enable unlimited polymorphism to gfortran

Tobias Burnus
Sun Dec 16 22:20:00 GMT 2012

Paul Richard Thomas wrote:
> The problem is with the way in which extends_type_of is organised.  It
> takes the _vptr directly.  Unless it is null for undefined pointers, a
> segfault is triggered.

So what? If I have:
   integer, pointer :: ptr
   ptr = 5
will also lead to a segfault (or a bus error); I do not see the 
difference. Here, the integer pointer "ptr" is not defj ned while for
   class(*), pointer :: poly_ptr
both the value (poly_ptr->_data) and the pointer to the virtual table 
(poly_ptr->_vptr) is uninitialized. I really do not see a difference. In 
any case, the Fortran standard explicitly doesn't allow code like
    class(*), pointer :: ptr, ptr2
    print *, same_type_as(ptr, ptr2)
as if either of the arguments is an undefined pointer. That's different 
to allocatables. Those are automatically in the nonallocatable state and 
    class(*), allocatable :: ptr, ptr2
    print *, same_type_as(ptr, ptr2)
is valid.

Side remark: I think the following code is always true as you use 
"attr.pointer" instead of "attr.class_pointer":

 > +  if (UNLIMITED_POLY (sym) && CLASS_DATA (sym)->attr.pointer)
 > +    gfc_defer_symbol_init (sym);

Still, I believe that the automatic definition of sym->_vptr should only 
be done for allocatables (i.e. nonpointers). As CLASS(...), allocatable 
is already handled, the three lines should go for good.

> I guess that I could achieve the same thing with the default initialization.

I am not sure whether I correctly understand this remark. I am think 
poly_ptr shouldn't be automatically be set, only via an explict pointer 
assignment, explict initialization, explict default initialization and 
explict "nullify()". Hence, I believe adding code which does so 
automatically - and not when the user explicitly ask for it - is a 
missed optimization (useless gfortran code plus in extra instructions 
(code size/performance) for the generated code).

> Initialization of class(*) pointers appears to be stuffed, as you
> point out.  I'll try to figure it out tomorrow night.

Thanks! Please also ensure that

integer, target :: tgt
type t
    class(*), pointer :: poly1 => null()
    class(*), pointer :: poly2 => tgt
! class(*), pointer :: poly3 => poly2  ! Invalid*
end type

is supported. (* I believe this line is invalid: the data-target needs to be something which is link-time resolvable and "poly3 => poly2" isn't as "poly3" has to point to the target of poly2 not to poly2.)


More information about the Gcc-patches mailing list