Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

ICE with 2017 U4, x64

OP1
New Contributor II
337 Views

The following program triggers an ICE with 2017 U4, Windows x64 configuration.

  1. Does this also occur with later versions of the compiler (we are considering an upgrade)
  2. Any suggestions to work around this?

Thanks!

MODULE M
IMPLICIT NONE
INTERFACE
    MODULE SUBROUTINE SUB(I)
        IMPLICIT NONE
        INTEGER :: I
    END SUBROUTINE SUB
    MODULE SUBROUTINE SET_SUB(USER_SUB)
        IMPLICIT NONE
        PROCEDURE(SUB) :: USER_SUB
    END SUBROUTINE SET_SUB
END INTERFACE
END MODULE M


SUBMODULE (M) SM
IMPLICIT NONE
PROCEDURE(SUB),POINTER :: INTERNAL_SUB  => NULL()
END SUBMODULE SM


SUBMODULE (M:SM) SET_SUB
IMPLICIT NONE
CONTAINS
    MODULE SUBROUTINE SET_SUB(USER_SUB)
        IMPLICIT NONE
        PROCEDURE(SUB) :: USER_SUB
        INTERNAL_SUB => USER_SUB
    END SUBROUTINE SET_SUB
END SUBMODULE SET_SUB


SUBMODULE (M:SM) SUB
IMPLICIT NONE
CONTAINS
    MODULE SUBROUTINE SUB(I)
        INTEGER :: I
        CALL INTERNAL_SUB(I)
    END SUBROUTINE SUB
END SUBMODULE SUB

 

0 Kudos
2 Replies
FortranFan
Honored Contributor II
337 Views

In your sub(sub)modules of SET_SUB and SUB respectively, you have conflicts with subprograms of the same names which I think (I've not checked) is disallowed by the standard.  Renaming the submodules, say to SET_SUB_SM and SUB_SM, doesn't help with Intel Fortran though the code then compiles successfully with gfortran.

Regardless the internal compiler error (always a compiler bug) persists with both 18.0 versions as well as 19.0 beta.  You should submit a support request at https://supporttickets.intel.com/?lang=en-US.

Re: a workaround, I don't know how you would view eliminating the 2 subhierarchies (which may be part of the problem with Intel Fortran) but it works:

MODULE M
   IMPLICIT NONE
   INTERFACE
      MODULE SUBROUTINE SUB(I)
         INTEGER :: I
      END SUBROUTINE SUB
      MODULE SUBROUTINE SET_SUB(USER_SUB)
         PROCEDURE(SUB) :: USER_SUB
      END SUBROUTINE SET_SUB
   END INTERFACE
END MODULE M

SUBMODULE (M) SM
   IMPLICIT NONE
   PROCEDURE(SUB), POINTER :: INTERNAL_SUB  => NULL()
CONTAINS
   MODULE SUBROUTINE SET_SUB(USER_SUB)
      PROCEDURE(SUB) :: USER_SUB
      INTERNAL_SUB => USER_SUB
   END SUBROUTINE SET_SUB
   MODULE SUBROUTINE SUB(I)
      INTEGER :: I
      CALL INTERNAL_SUB(I)
   END SUBROUTINE SUB
END SUBMODULE SM

 

0 Kudos
OP1
New Contributor II
336 Views

Thanks for the suggestions!

Regarding the conflict between submodule names and module subroutine names, it has not been an issue so far... I am not sure what the standard says about this.

I found another workaround: by declaring an abstract interface in the submodule SM as shown in the code below, it works. However, if that same abstract interface block is placed in the module M, I get an ICE. So it looks like the interface inheritance mechanism is broken from a module to (any) submodule, but not from a submodule to a subsubmodule.

MODULE M
IMPLICIT NONE
INTERFACE
    MODULE SUBROUTINE SUB(I)
        IMPLICIT NONE
        INTEGER :: I
    END SUBROUTINE SUB
    MODULE SUBROUTINE SET_SUB(USER_SUB)
        IMPLICIT NONE
        PROCEDURE(SUB) :: USER_SUB
    END SUBROUTINE SET_SUB
END INTERFACE
END MODULE M


SUBMODULE (M) SM
IMPLICIT NONE
ABSTRACT INTERFACE                  ! This abstract interface should not be
    SUBROUTINE SUB_INTERFACE(I)     ! be required here. Line 24 should just
        IMPLICIT NONE               ! be PROCEDURE(SUB),POINTER... but for
        INTEGER :: I                ! some reason the SUB interface is not
    END SUBROUTINE SUB_INTERFACE    ! passed to the submodules.
END INTERFACE
PROCEDURE(SUB_INTERFACE),POINTER :: INTERNAL_SUB  => NULL()
END SUBMODULE SM


SUBMODULE (M:SM) SET_SUB
IMPLICIT NONE
CONTAINS
    MODULE SUBROUTINE SET_SUB(USER_SUB)
        IMPLICIT NONE
        PROCEDURE(SUB_INTERFACE) :: USER_SUB
        INTERNAL_SUB => USER_SUB
    END SUBROUTINE SET_SUB
END SUBMODULE SET_SUB


SUBMODULE (M:SM) SUB
IMPLICIT NONE
CONTAINS
    MODULE SUBROUTINE SUB(I)
        INTEGER :: I
        CALL INTERNAL_SUB(I)
    END SUBROUTINE SUB
END SUBMODULE SUB


PROGRAM P
USE M
IMPLICIT NONE
    CALL SET_SUB(USER_SUB_1)
    CALL SUB(1)
    CALL SET_SUB(USER_SUB_2)
    CALL SUB(1)
CONTAINS
    SUBROUTINE USER_SUB_1(I)
        IMPLICIT NONE
        INTEGER :: I
        WRITE(*,*) I
    END SUBROUTINE USER_SUB_1
    SUBROUTINE USER_SUB_2(I)
        IMPLICIT NONE
        INTEGER :: I
        WRITE(*,*) I+1
    END SUBROUTINE USER_SUB_2
END PROGRAM P

 

0 Kudos
Reply