Dear Steve et al. at Intel,
Can you please review the code shown below and check whether it is ok to have a superfluous GENERIC OPERATOR specification in an extended derived type that is simply a copy of one in the abstract parent? See lines 17 and 47 in the code snippet, a heavily simplified version of my actual type.
This code compiles without any errors or warnings in Intel Fortran XE 2013, Update 1 even if standards checking is turned on.
However, gfortran 4.9 flags an error saying the two procedures for the + operator are ambiguous.
It looks ok to me even though in my actual code, the specification in the child was just by accident, I have no need for it, and I've since removed it. But if gfortran is correct, it will help to get Intel Fortran to generate some sort of error or a warning.
Since a few other trouble incidents have come up recently in connection with resolution of ambiguous references in GENERIC statements in extended derived types, this example may possibly be of interest to your developers. If appropriate, please attach this to one or more of those tracking incidents.
Thanks much.
MODULE m IMPLICIT NONE !.. PRIVATE !.. Mnemonic constants INTEGER, PARAMETER, PUBLIC :: IMISS = -9999 TYPE, ABSTRACT, PUBLIC :: p PRIVATE CONTAINS PRIVATE PROCEDURE(IAdd_p), PASS(Lhs), DEFERRED :: Add_p PROCEDURE(IInit_p), PASS(This), DEFERRED, PUBLIC :: Init GENERIC, PUBLIC :: OPERATOR(+) => Add_p END TYPE p ABSTRACT INTERFACE PURE ELEMENTAL FUNCTION IAdd_p(Lhs, Rhs) RESULT(LhsPlusRhs) IMPORT :: p !.. Argument list CLASS(p), INTENT(IN) :: Lhs CLASS(p), INTENT(IN) :: Rhs !.. Function result CLASS(p), ALLOCATABLE :: LhsPlusRhs END FUNCTION IAdd_p PURE ELEMENTAL SUBROUTINE IInit_p(This, InitVal) IMPORT :: p !.. Argument list CLASS(p), INTENT(INOUT) :: This INTEGER, INTENT(IN) :: InitVal END SUBROUTINE IInit_p END INTERFACE TYPE, EXTENDS(p), PUBLIC :: c PRIVATE INTEGER :: foo CONTAINS PRIVATE PROCEDURE, PASS(Lhs) :: Add_p => Add_c PROCEDURE, PASS(This), PUBLIC :: Init => Init_c GENERIC, PUBLIC :: OPERATOR(+) => Add_p END TYPE c CONTAINS PURE ELEMENTAL FUNCTION Add_c(Lhs, Rhs) RESULT(LhsPlusRhs) !.. Argument list CLASS(c), INTENT(IN) :: Lhs CLASS(p), INTENT(IN) :: Rhs !.. Function result CLASS(p), ALLOCATABLE :: LhsPlusRhs !.. Local variables INTEGER :: Istat TYPE(c), ALLOCATABLE :: NewChild !.. ALLOCATE(NewChild, SOURCE=Lhs, STAT=Istat) IF (Istat /= 0) THEN ALLOCATE( c :: LhsPlusRhs, STAT=Istat) IF (Istat == 0) THEN CALL LhsPlusRhs%Init(IMISS) END IF !.. Insert error handling here RETURN END IF SELECT TYPE(Rhs) CLASS IS (c) NewChild%foo = Lhs%foo + Rhs%foo CLASS DEFAULT !.. Not yet supported NewChild%foo = IMISS END SELECT !.. CALL MOVE_ALLOC( NewChild, LhsPlusRhs ) !.. RETURN END FUNCTION Add_c PURE ELEMENTAL SUBROUTINE Init_c(This, InitVal) !.. Argument list CLASS(c), INTENT(INOUT) :: This INTEGER, INTENT(IN) :: InitVal !.. This%foo = InitVal RETURN END SUBROUTINE Init_c END MODULE m