[Bug fortran/55057] New: [OOP] wrong result with abstract type
mrestelli at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Oct 24 15:36:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55057
Bug #: 55057
Summary: [OOP] wrong result with abstract type
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: mrestelli@gmail.com
The attached code compiles and runs, but the results are not correct.
Unfortunately the reduced test is not very much reduced, however I
think the problem is that in alt the storages of x, y and z overlap.
Notice that the problem is present only when calling alt through an
additional subroutine sub, as indicated by the comments.
gfortran --version
GNU Fortran (GCC) 4.8.0 20121024 (experimental)
./test
All the following values should be 2.0
2.00000000
2.00000000
2.00000000
All the following values should be 2.0
2.00000000
3.00000000
6.00000000
module m
implicit none
public :: &
at1, at2, t1, t2, sub
private
type, abstract :: at1
contains
procedure(i_copy), deferred, pass(z) :: copy
procedure(i_incr), deferred, pass(x) :: incr
procedure(i_tims), deferred, pass(x) :: tims
procedure(i_show), deferred, pass(x) :: show
procedure, pass(z) :: add
procedure, pass(z) :: mlt
procedure, pass(z) :: alt
end type at1
abstract interface
pure subroutine i_copy(z,x)
import :: at1
implicit none
class(at1), intent(in) :: x
class(at1), intent(inout) :: z
end subroutine i_copy
end interface
abstract interface
pure subroutine i_incr(x,y)
import :: at1
implicit none
class(at1), intent(in) :: y
class(at1), intent(inout) :: x
end subroutine i_incr
end interface
abstract interface
pure subroutine i_tims(x,r)
import :: at1
implicit none
real, intent(in) :: r
class(at1), intent(inout) :: x
end subroutine i_tims
end interface
abstract interface
subroutine i_show(x)
import :: at1
implicit none
class(at1), intent(in) :: x
end subroutine i_show
end interface
type, abstract :: at2
class(at1), allocatable :: work(:)
end type at2
type, extends(at1) :: t1
real, allocatable :: f(:)
contains
procedure, pass(x) :: incr
procedure, pass(x) :: tims
procedure, pass(z) :: copy
procedure, pass(x) :: show
end type t1
type, extends(at2) :: t2
end type t2
contains
subroutine alt(z,x,r,y)
real, intent(in) :: r
class(at1), intent(in) :: x, y
class(at1), intent(inout) :: z
print *, 'All the following values should be 2.0'
call y%show()
call z%mlt(r,y) ! z = r * y
call y%show()
call z%incr(x) ! z = z + x
call y%show()
end subroutine alt
pure subroutine add(z,x,y)
class(at1), intent(in) :: x, y
class(at1), intent(inout) :: z
call z%copy( x )
call z%incr( y )
end subroutine add
pure subroutine mlt(z,r,x)
real, intent(in) :: r
class(at1), intent(in) :: x
class(at1), intent(inout) :: z
call z%copy( x )
call z%tims( r )
end subroutine mlt
pure subroutine copy(z,x)
class(at1), intent(in) :: x
class(t1), intent(inout) :: z
select type(x); type is(t1)
z%f = x%f
end select
end subroutine copy
pure subroutine incr(x,y)
class(at1), intent(in) :: y
class(t1), intent(inout) :: x
select type(y); type is(t1)
x%f = x%f + y%f
end select
end subroutine incr
pure subroutine tims(x,r)
real, intent(in) :: r
class(t1), intent(inout) :: x
x%f = r*x%f
end subroutine tims
subroutine show(x)
class(t1), intent(in) :: x
write(*,*) x%f
end subroutine show
subroutine sub(var)
class(at2), intent(inout) :: var
call var%work(2)%alt(var%work(1),1.5,var%work(1))
end subroutine sub
end module m
program p
use m, only: t1, t2, sub
implicit none
integer :: i
type(t2) :: aa
allocate(t1::aa%work(2))
select type(y=>aa%work); type is(t1)
do i=1,2
allocate(y(i)%f(1))
y(i)%f = 2.0
enddo
end select
! This call to ALT works as expected
call aa%work(2)%alt(aa%work(1),1.5,aa%work(1))
! Calling ALT from SUB however does not work
call sub(aa)
end program p
More information about the Gcc-bugs
mailing list