Showing results for 
Search instead for 
Did you mean: 

Module Scope Issue

I have a really specific obscure bug I've found with getting some code to compile with both Intel Fortran (I'm using version Build 20170213) and gfortran 6.2. I apologize in advance for my horrible overly long example code, it's simplified by quite a bit from the code from which the issue arose. In this example code, I have 3 modules: (1) A module "polymod" that defines a type "Thing"; (2) a module "testpolytype" that has a type "SimpleType" that has a type bound procedure that has a dummy argument of type "Thing"; (3) a module that has a function (TestUseWithTypeDef) that uses variables of type SimpleType and type Thing to call the type bound procedure in SimpleType.

*The attached code will not compile in gfortran (as I would expect, I get "Error: Derived type ‘thing’ at (1) is being used before it is defined"), if I don't explicitly "use polymod" (line 51) in the function "TestUseWithTypeDef", but compiles with intel fortran unless I specifically state "use testpolymod, only: SimpleType" (line 52). It seems to me that SimpleType should not come in to scope because it is used in a type bound procedure that is being called. Or am I misunderstanding some weird scoping issue with typebound procedures?*

module polymod
    implicit none

    interface Thing
        module procedure Initialize
    end interface Thing

    type :: Thing
        integer :: thingProp
    end type Thing


    subroutine Initialize(this, thingProp)
        class(Thing) :: this
        integer, intent(in) :: thingProp

        this%thingProp = thingProp

    end subroutine Initialize

end module polymod

module testpolymod
    implicit none

    type SimpleType

        procedure, public :: UseThing
    end type SimpleType

    subroutine UseThing(this,dummyThing)
        use polymod
        class(SimpleType) :: this
        type(Thing), intent(inout) :: dummyThing

        dummyThing = Thing(42)

    end subroutine UseThing

end module testpolymod

module callermod
    implicit none

    function TestUseWithTypeDef() result(intOut)
!        use polymod
        use  testpolymod
        integer :: intOut
        type(SimpleType) :: sT
        type(Thing) :: local_thing

        call sT%UseThing(local_thing)
        write(*,*)"thing prop: ", local_thing%thingProp

        intOut = local_thing%thingProp
    end function TestUseWithTypeDef

end module callermod

program testpoly
    use callermod
    implicit none


end program testpoly


0 Kudos
2 Replies
Black Belt Retired Employee

I agree with you - this should not compile. The specific issue is the reference to type thing in line 55. This is NOT a type exported by module testpolymod and hence is inaccessible in the function. I recall seeing similar issues of declarations "leaking" in similar circumstances.

0 Kudos

Thank you for reporting this defect and for the nice test case. I confirmed the findings and reported this to Development.

(Internal tracking id: DPD200419969)

0 Kudos