Hi,
pgfortran does not compile the attached code. The error message is:
PGF90-S-0099-Illegal use of operator == on a derived type (illegal_use.f90: 135)
PGF90-S-0099-Illegal use of derived type (illegal_use.f90: 135)
PGF90-S-0099-Illegal use of derived type (illegal_use.f90: 135)
PGF90-S-0099-Illegal use of operator == on a derived type (illegal_use.f90: 135)
PGF90-S-0099-Illegal use of derived type (illegal_use.f90: 135)
PGF90-S-0099-Illegal use of derived type (illegal_use.f90: 135)
PGF90-S-0099-Illegal use of operator == on a derived type (illegal_use.f90: 138)
PGF90-S-0099-Illegal use of derived type (illegal_use.f90: 138)
PGF90-S-0099-Illegal use of derived type (illegal_use.f90: 138)
0 inform, 0 warnings, 9 severes, 0 fatal for secondsto
I’m not entirely sure if this is a compiler bug or not, but neither nagfor nor ifort has any issues with this code.
The issue seem to be that both binding-names in HSJulianDay are identical to actual procedures in the same module. The program compiles if I change one of the binding names in HSJulianDay or if I change the names of the type-bound procedures in HSDateTime and use binding names instead.
Best regards,
Øystein
MODULE HS2Kinds
USE ISO_FORTRAN_ENV, ONLY: INT8, INT16, INT32, INT64
USE ISO_FORTRAN_ENV, ONLY: REAL32, REAL64
IMPLICIT NONE
PUBLIC
INTEGER, PARAMETER :: I1B = INT8 !SELECTED_INT_KIND(2)
INTEGER, PARAMETER :: I2B = INT16 !SELECTED_INT_KIND(4)
INTEGER, PARAMETER :: I4B = INT32 !SELECTED_INT_KIND(9)
INTEGER, PARAMETER :: L1B = KIND(.TRUE.) !LOGICAL_KINDS(1)
INTEGER, PARAMETER :: LP = REAL32
INTEGER, PARAMETER :: HP = REAL64
INTEGER, PARAMETER :: WP = HP
INTEGER(I1B), PARAMETER :: MAXI1B = HUGE(1_I1B)
INTEGER(I2B), PARAMETER :: MAXI2B = HUGE(1_I2B)
INTEGER(I4B), PARAMETER :: MAXI4B = HUGE(1_I4B)
END MODULE HS2Kinds
MODULE HS2DateTime
USE HS2Kinds
IMPLICIT NONE
PRIVATE
SAVE
PUBLIC :: HSJulianDay
PUBLIC :: HSDateTime
TYPE HSTimeSpec
INTEGER(I1B), PRIVATE :: val = 2
CONTAINS
GENERIC :: OPERATOR(==) => timeSpecsAreEqual
PROCEDURE, PRIVATE, PASS :: timeSpecsAreEqual
GENERIC :: ASSIGNMENT(=) => setTimeSpec
PROCEDURE, PRIVATE, PASS :: setTimeSpec
END TYPE HSTimeSpec
TYPE(HSTimeSpec), PARAMETER :: HSUTC = HSTimeSpec(0)
TYPE HSJulianDay
INTEGER(I4B) :: JDN = 2451545
REAL(HP) :: FD = 0.0_HP
TYPE(HSTimeSpec) :: spec = HSUTC
CONTAINS
! BUG? Either changing one of the binding names fixes PGF90-S-0099
PROCEDURE, PASS :: msecondsTo => msecondsToJD
PROCEDURE, PASS :: secondsTo => secondsToJD
END TYPE HSJulianDay
TYPE HSDateTime
INTEGER(I2B) :: year = 2000
INTEGER(I1B) :: month = 1, day = 1
INTEGER(I1B) :: hour = 12, minute = 0, second = 0
CONTAINS
! BUG? Changing the name of the actual routines work.
PROCEDURE, PASS :: msecondsTo
PROCEDURE, PASS :: secondsTo
!PROCEDURE, PASS :: msecondsTo => msecondsToDT
!PROCEDURE, PASS :: secondsTo => secondsToDT
END TYPE HSDateTime
CONTAINS
ELEMENTAL SUBROUTINE setTimeSpec(a, b)
CLASS(HSTimeSpec), INTENT(INOUT) :: a
TYPE(HSTimeSpec), INTENT(IN) :: b
a%val = b%val
RETURN
END SUBROUTINE setTimeSpec
ELEMENTAL FUNCTION timeSpecsAreEqual(a, b) RESULT(answ)
CLASS(HSTimeSpec), INTENT(IN) :: a
TYPE(HSTimeSpec), INTENT(IN) :: b
LOGICAL(L1B) :: answ
answ = (a%val == b%val)
RETURN
END FUNCTION timeSpecsAreEqual
ELEMENTAL FUNCTION msecondsToJD(this,to) RESULT (answ)
CLASS(HSJulianDay), INTENT(IN) :: this
TYPE(HSJulianDay), INTENT(IN) :: to
REAL(HP) :: answ
answ = to%FD - this%FD
answ = REAL(to%JDN - this%JDN, HP) + answ
answ = answ*86400.0_HP
answ = answ*1000.0_HP
RETURN
END FUNCTION msecondsToJD
ELEMENTAL FUNCTION secondsToJD(this,to) RESULT (answ)
CLASS(HSJulianDay), INTENT(IN) :: this
TYPE(HSJulianDay), INTENT(IN) :: to
REAL(HP) :: answ
answ = to%FD - this%FD
answ = REAL(to%JDN - this%JDN, HP) + answ
answ = answ*86400.0_HP
RETURN
END FUNCTION secondsToJD
FUNCTION msecondsTo(this,to) RESULT (answ)
CLASS(HSDateTime), INTENT(IN) :: this
TYPE(HSDateTime), INTENT(IN) :: to
REAL(HP) :: answ
answ = secondsTo(this, to)*1000.0_HP
RETURN
END FUNCTION msecondsTo
FUNCTION secondsTo(this,to) RESULT (answ)
CLASS(HSDateTime), INTENT(IN) :: this
TYPE(HSDateTime), INTENT(IN) :: to
REAL(HP) :: answ
TYPE(HSJulianDay) :: jd1, jd2
!jd1 = this%toJulianDay()
!jd2 = to%toJulianDay()
IF (jd1%spec == HSUTC .AND. jd2%spec == HSUTC) THEN
WRITE(*,*) "CALL jd1%toTimeSpec(HSTT)"
WRITE(*,*) "CALL jd2%toTimeSpec(HSTT)"
ELSE IF (jd1%spec == HSUTC) THEN
WRITE(*,*) "CALL jd1%toTimeSpec(jd2%spec)"
ELSE
WRITE(*,*) "CALL jd2%toTimeSpec(jd1%spec)"
END IF
answ = secondsToJD(jd1, jd2)
RETURN
END FUNCTION secondsTo
END MODULE HS2DateTime
PROGRAM test_hsdatetime
USE HS2DateTime
WRITE(*,*) "compiled successfully"
END PROGRAM test_hsdatetime