From: Damian on
If an extended type overrides a type-bound procedure of its abstract
parent, can it explicitly invoke the parent's version on of the
procedure on the parent component? The code below works if I delete
the "abstract" attribute from the parent type. With the abstract
attribute, I get the error below from gfortran 4.5.0 20100103
(experimental) [trunk revision 155591]:

$ cat abstract_parent.f03
module parent_module
implicit none

type ,abstract :: parent
contains
procedure :: foo
end type

contains
subroutine foo(this)
class(parent) :: this
print *,'Inside parent foo'
end subroutine
end module

module child_module
use parent_module
implicit none

type ,extends(parent) :: child
contains
procedure :: foo => foo_child
end type

contains
subroutine foo_child(this)
class(child) :: this
print *,'Inside child foo'
call this%parent%foo()
end subroutine
end module
$ $ gfortran -c abstract_parent.f03
abstract_parent.f03:29.13:

call this%parent%foo()
1
Error: Base object for type-bound procedure call at (1) is of ABSTRACT
type 'parent'
From: Tobias Burnus on
Damian wrote:
> If an extended type overrides a type-bound procedure of its abstract
> parent, can it explicitly invoke the parent's version on of the
> procedure on the parent component?

I think it can - as long as it is not DEFERRED. The standard is crafted
such that one cannot invoke a type-bound procedure with a deferred
attribute via

C427 (R429) If the type definition contains or inherits (4.5.6.1) a
deferred binding (4.5.4), ABSTRACT shall appear.

Thus, one can never have a dynamic type which has not overridden this
attribute and thus one cannot call this procedure (cf. also NOTE 4.50).

However, I could not find anything, which prohibits calling a
non-deferred type-bound procedure, declared in an abstract type. Neither
in data-ref (R612, R613, C611) nor at the procedure invocation (R1219,
C1223, C1224, Sect. 12.4.5).

Actually, if you do not override a procedure, calling "child%tbp()" and
"child%parent%tbp()" invokes the same procedure with the same arguments
- still gfortran rejects the "child%parent%tbp()" call.

Thus, I think your program is valid. The error probably came about when
trying to prevent calling a deferred procedure, but the checking is too
broad. I will file a bugreport against gfortran.

Thanks for the report!

Tobias

PS: PR see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43193
From: Tobias Burnus on
Am 27.02.2010 00:57, schrieb Tobias Burnus:
> Damian wrote:
>> If an extended type overrides a type-bound procedure of its abstract
>> parent, can it explicitly invoke the parent's version on of the
>> procedure on the parent component?
>
> However, I could not find anything, which prohibits calling a
> non-deferred type-bound procedure, declared in an abstract type. Neither
> in data-ref (R612, R613, C611) nor at the procedure invocation (R1219,
> C1223, C1224, Sect. 12.4.5).

It helps if one reads correctly R1219 and *then* checks what R611/C611
has. One then realizes that type%parent%tpb() is invalid - as Jim Xia
kindly pointed out to me.

R611 data-ref is part-ref [ % part-ref ] ...
C611 (R611) If the rightmost part-name is of abstract type,
data-ref shall be polymorphic.

Thus, for a valid data-ref: In "something%parent" parent needs to by
polymorphic (or not abstract).

And for the call, one simply appends "% binding-name" to that data-ref:

R1219 procedure designator is [...] or data-ref % binding-name

Therefore, the call is invalid and gfortran handles the constrain correctly.

Sorry for misreading.

Tobias

PS: I think I have misread "binding-name" as "part-ref" yesterday evening.

PPS: My old NAG f95 v5.1 writes "ERROR: PARENT is not of derived type"
which is not quite right - though also not completely wrong either.
While ifort 11.1 even compiles type%parent%deferred_tbp - though it has
an internal error if "procedure(procintf), deferred...". If you wonder
what happens, if you call it? Well, it simply invokes "procintf" ...
From: Damian on
On Feb 27, 7:27 am, Tobias Burnus <bur...(a)net-b.de> wrote:
> Am 27.02.2010 00:57, schrieb Tobias Burnus:
>
> > Damian wrote:
> >> If an extended type overrides a type-bound procedure of its abstract
> >> parent, can it explicitly invoke the parent's version on of the
> >> procedure on the parent component?
>
> > However, I could not find anything, which prohibits calling a
> > non-deferred type-bound procedure, declared in an abstract type. Neither
> > in data-ref (R612, R613, C611) nor at the procedure invocation (R1219,
> > C1223, C1224, Sect. 12.4.5).
>
> It helps if one reads correctly R1219 and *then* checks what R611/C611
> has. One then realizes that  type%parent%tpb()  is invalid - as Jim Xia
> kindly pointed out to me.
>
>   R611 data-ref is part-ref [ % part-ref ] ...
>   C611 (R611) If the rightmost part-name is of abstract type,
>               data-ref shall be polymorphic.
>
> Thus, for a valid data-ref: In "something%parent" parent needs to by
> polymorphic (or not abstract).
>
> And for the call, one simply appends "% binding-name" to that data-ref:
>
>   R1219 procedure designator is [...] or  data-ref % binding-name
>
> Therefore, the call is invalid and gfortran handles the constrain correctly.
>
> Sorry for misreading.
>
> Tobias
>
> PS: I think I have misread "binding-name" as "part-ref" yesterday evening..
>
> PPS: My old NAG f95 v5.1 writes "ERROR: PARENT is not of derived type"
> which is not quite right - though also not completely wrong either.
> While ifort 11.1 even compiles type%parent%deferred_tbp - though it has
> an internal error if "procedure(procintf), deferred...". If you wonder
> what happens, if you call it? Well, it simply invokes "procintf" ...

So how do I make the rightmost component polymorphic? I tried
changing foo_child to the following:

subroutine foo_child(this)
class(child) :: this
class(parent) ,pointer :: this_parent=>null()
this_parent => this%parent
print *,'Inside child foo'
call this_parent%foo()
end subroutine

With this revision, gfortran 4.5.0 20100103 (experimental) [trunk
revision 155591] terminates with an internal compiler error. IBM XL
Fortran 5.1 gives

bash-3.2$ xlf2003 Final_test.F90
** parent_module === End of Compilation 1 ===
"Final_test.F90", line 27.20: 1514-648 (S) A structure component
reference must be polymorphic if the rightmost component name is of
abstract type.
** child_module === End of Compilation 2 ===
1501-511 Compilation failed for file Final_test.F90.

where line 27 is the pointer assignment "this_parent => this%parent".
Actually, I guess I understand this error. I just can't see a
workaround if I want to invoke a TBP defined by the parent in
situations where that TBP has been overridden by the child. Does
overriding the parent's TBP prevent me from ever using the version
defined in the parent?

Damian

Damian