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
hence
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.)
Tobias