https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117730

            Bug ID: 117730
           Summary: Wrong code with non_overridable typebound procedure
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: pault at gcc dot gnu.org
          Reporter: pault at gcc dot gnu.org
  Target Milestone: ---

Extracted from comment #4 in PR84674 and posted by dar...@web.de

With a debugger, I could see: in test.f90, F%get() is called (line 8), the
program then moves into child_get() in module2.f90 (line 35) as it should.
However, stepping into this%calc() (line 39), it moves to child_reset() in
module1.f90 (line 31) instead of child2_calc() in module2.f90 (line 15).

There are two ways to get this program to work, which are both quite weird:
1. (correct version of this in comment #5)remove "non_overridable" from line 13
in module1.f90
s/procedure, pass, non_overridable :: reset => child_reset/procedure, pass ::
get => child_reset/

2. merge module1 and module2 into one module.

3. added by pault: delete line 13 in module1.f90
        d/procedure, pass :: reset => parent_reset/


FILES:
***module1.f90:
module module1
    implicit none
    private
    public :: child

    type, abstract :: parent
    contains
        procedure, pass :: reset => parent_reset
    end type parent

    type, extends(parent), abstract :: child
    contains
        procedure, pass, non_overridable :: reset => child_reset
        procedure, pass, non_overridable :: get => child_get
        procedure(calc_i), pass, deferred :: calc
    end type child

    abstract interface
        pure function calc_i(this) result(value)
            import :: child
            class(child), intent(in) :: this
            integer                 :: value
        end function calc_i
    end interface

contains
    pure subroutine parent_reset(this)
        class(parent), intent(inout) :: this
    end subroutine parent_reset

    pure subroutine child_reset(this)
        class(child), intent(inout) :: this
    end subroutine child_reset

    function child_get(this) result(value)
        class(child), intent(inout) :: this
        integer                   :: value

        value = this%calc()
    end function child_get
end module module1

***module2.f90:
module module2
    use module1, only: child

    implicit none
    private
    public :: child2

    type, extends(child) :: child2
    contains
        procedure, pass :: calc => child2_calc
    end type child2

contains

    pure function child2_calc(this) result(value)
        class(child2), intent(in) :: this
        integer :: value

        value = 1
    end function child2_calc

end module module2

***test.f90:
program test
    use module2, only: child2

    implicit none

    type(child2) :: F

    if (F%get() /= 1) stop ': FAILED'

end program test

Reply via email to