From: Damian on 26 Feb 2010 17:12 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 26 Feb 2010 18:57 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 27 Feb 2010 10:27 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 27 Feb 2010 19:51 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
|
Pages: 1 Prev: Verifying function interface Next: Overriding assignment and array slicing |