Second program causing an ICE

Arjen Markus arjen.markus895@gmail.com
Sun Feb 13 11:03:00 GMT 2011


Hello,

here is the second program that causes an internal compiler error.
This time the message includes the name of a routine -
gfc+enforce_symbol_state in fortran/symbol.c
(line 3482)

The program is this (again: I know it is incorrect and I have achieved
what I wanted in a different way):


! classes_geom.f90 --
!     Classes of geometrical objects as an illustration
!     of object-oriented programming in Fortran
!
module geometrical_objects

    implicit none

    !
    ! General shape
    !
    type, abstract :: shape
        ! No data
    contains
        procedure(get_shape_area), deferred           :: get_area
        procedure(assign_shape), deferred, pass(that) :: assign_type_to_shape
        generic                                       :: assignment(=)
=> assign_type_to_shape
        !procedure                                    :: size  -- does not work
    end type shape

    abstract interface
        real function get_shape_area( this )
            import                   :: shape
            class(shape), intent(in) :: this
        end function get_shape_area
    end interface

    abstract interface
        subroutine assign_shape( this, that )
            import                      :: shape
            class(shape), intent(inout) :: this
            class(shape), intent(in)    :: that
        end subroutine assign_shape
    end interface

    !
    ! Rectangle
    !
    type, extends(shape) :: rectangle
        real :: width, height
    contains
        procedure :: get_area             => get_rectangle_area
        procedure :: size                 => rectangle_size
        procedure, pass(that) :: assign_type_to_shape => assign_rectangle
    end type rectangle

    !
    ! Square
    ! Note:
    ! square_size must have the same interface as its rectangle parent!
    !
    type, extends(rectangle) :: square
    contains
        procedure :: size => square_size
        procedure :: assign_type_to_shape => assign_square
    end type square

contains

!
! The various routines and functions we need
!
real function get_rectangle_area( this )
    class(rectangle), intent(in) :: this

    get_rectangle_area = this%width * this%height

end function get_rectangle_area

subroutine rectangle_size( this, width, height )
    class(rectangle), intent(inout) :: this
    real, intent(in)                :: width
    real, intent(in), optional      :: height

    this%width  = width
    if ( present(height) ) then
        this%height = height
    else
        this%height = width
    endif

end subroutine rectangle_size

subroutine assign_rectangle( this, that )
    class(shape),     intent(inout) :: this
    class(rectangle), intent(in)    :: that

    select type( that )
        class is (rectangle)
            this = that
    end select

end subroutine assign_rectangle

subroutine square_size( this, width, height )
    class(square), intent(inout) :: this
    real, intent(in)             :: width
    real, intent(in), optional   :: height  ! Ignored

    this%width  = width
    this%height = width

end subroutine square_size

subroutine assign_square( this, that )
    class(shape),  intent(inout) :: this
    class(square), intent(in)    :: that

    select type( that )
        class is (square)
            this = that
    end select

end subroutine assign_square

end module geometrical_objects

!
! Small test program
program test_objects

    use geometrical_objects

    implicit none

    class(shape), dimension(2) :: object
    type(rectangle)            :: rect
    type(square)               :: sq

    call rect%size( 1.0, 2.0 )
    call sq%size( 1.5 )

    object(1) = rect
    object(2) = sq

    do i = 1,size(object)
        write(*,*) 'Area: ', object(i)%get_area()
    enddo

contains

end program test_objects

Regards,

Arjen



More information about the Fortran mailing list