Possible Fortran compiler bug with intrinsic trim function call

I get the following compiler messages

nvfortran -c date_module_implementation.f90
NVFORTRAN-S-0074-Illegal number or type of arguments to trim - keyword argument string (date_module_implementation.f90: 179)
NVFORTRAN-S-0146-Expression must be character type (date_module_implementation.f90: 179)
NVFORTRAN-S-0075-Subscript, substring, or argument illegal in this context for month (date_module_implementation.f90: 188)
NVFORTRAN-S-0146-Expression must be character type (date_module_implementation.f90: 188)
NVFORTRAN-S-0146-Expression must be character type (date_module_implementation.f90: 192)
NVFORTRAN-S-0038-Symbol, day, has not been explicitly declared (date_module_implementation.f90)
NVFORTRAN-S-0038-Symbol, month, has not been explicitly declared (date_module_implementation.f90)
  0 inform,   0 warnings,   7 severes, 0 fatal for print_date

when trying to compile the following code

submodule (date_module_interface) &
  date_module_implementation


contains

  module function &
    calendar_to_julian(this) &
    result (ival)
    implicit none
    integer :: ival
    class (date), intent (in) :: this

    ival = this%day - 32075 + 1461*&
      (this%year+ &
      4800+(this%month-14)/12)/4 + &
      367*(this%month-2-((this%month- &
      14)/12)*12)/12 - 3*&
      ((this%year+4900+(this% &
      month-14)/12)/100)/4
  end function calendar_to_julian

  type (date) module function &
    date_constructor(dd, mm, &
    yyyy)

    implicit none
    integer, intent (in) :: dd, mm, yyyy

    date_constructor%day = dd
    date_constructor%month = mm
    date_constructor%year = yyyy

  end function date_constructor

  integer module function &
    date_to_day_in_year(this)
    implicit none
    class (date), intent (in) :: this
    intrinsic modulo

    date_to_day_in_year = 3055*&
        (this%month+2)/ &
      100 - (this%month+10)/13*2 - &
        91 + &
      (1-(modulo(this%year,4)+3)/4+&
        (modulo(this% &
      year,100)+99)/100-(modulo(this%year, &
      400)+399)/400)*(this%month+10)/13 + &
      this%day
  end function date_to_day_in_year

  integer module function &
    date_to_weekday_number(this)
    implicit none
    class (date), intent (in) :: this
    intrinsic modulo

    date_to_weekday_number = modulo((13*( &
      this%month+10-&
        (this%month+10)/13*12)-1)/5+ &
      this%day+77+5*(this%year+(this%month- &
      14)/12-(this%year+&
        (this%month-14)/12)/100* &
      100)/4+(this%year+(this%month- &
      14)/12)/400-(this%year+(this%month- &
      14)/12)/100*2, 7)
  end function date_to_weekday_number

  module function get_day(this)
    implicit none
    integer :: get_day
    class (date), intent (in) :: this

    get_day = this%day
  end function get_day

  module function get_month(this)
    implicit none
    integer :: get_month
    class (date), intent (in) :: this

    get_month = this%month
  end function get_month

  module function get_year(this)
    implicit none
    integer :: get_year
    class (date), intent (in) :: this

    get_year = this%year
  end function get_year

  module function julian_to_date(julian)
    implicit none
    type (date) :: julian_to_date
    integer, intent (in) :: julian

    integer :: l, n

    l = julian + 68569
    n = 4*l/146097
    l = l - (146097*n+3)/4
    julian_to_date%year = (4000*(l+1)/1461001)
    l = l - 1461*julian_to_date%year/4 + 31
    julian_to_date%month = (80*l/2447)
    julian_to_date%day = &
      (l-2447*julian_to_date% &
      month/80)
    l = julian_to_date%month/11
    julian_to_date%month = &
       (julian_to_date%month &
      +2-12*l)
    julian_to_date%year = (100*(n-49)+ &
      julian_to_date%year+1)
  end function julian_to_date

  module subroutine &
    julian_to_date_and_week_and_day(jd, &
    d, wd, ddd)
    implicit none
    integer, intent (in) :: jd
    type (date), intent (out) :: d
    integer, intent (out) :: wd, ddd

    d = julian_to_date(jd)
    wd = date_to_weekday_number(d)
    ddd = date_to_day_in_year(d)
  end subroutine &
    julian_to_date_and_week_and_day

  module function ndays(date1, date2)
    implicit none
    integer :: ndays
    class (date), intent (in) :: date1, date2

    ndays = calendar_to_julian(date1) - &
      calendar_to_julian(date2)
  end function ndays

  module function &
    print_date(this, day_names, &
    short_month_name, digits)
    implicit none
    class (date), intent (in) :: this
    logical, optional, intent (in) :: &
      day_names, &
      short_month_name, digits
    character (40) :: print_date
    integer :: pos
    logical :: want_day, &
      want_short_month_name, &
      want_digits
    intrinsic len_trim, present, trim

    want_day = .false.
    want_short_month_name = .false.
    want_digits = .false.
    print_date = ' '
    if (present(day_names)) then
      want_day = day_names
    end if
    if (present(short_month_name)) then
      want_short_month_name = short_month_name
    end if
    if (present(digits)) then
      want_digits = digits
    end if
    if (want_digits) then
      write (print_date(1:2), '(i2)') this%day
      print_date(3:3) = '/'
      write (print_date(4:5), '(i2)') &
        this%month
      print_date(6:6) = '/'
      write (print_date(7:10), '(i4)') this%year
    else
      if (want_day) then
        pos = date_to_weekday_number(this)
        print_date = trim(day(pos)) // ' '
        pos = len_trim(print_date) + 2
      else
        pos = 1
        print_date = ' '
      end if
      write (print_date(pos:pos+1), '(i2)') &
        this%day
      if (want_short_month_name) then
        print_date(pos+3:pos+5) = month(this% &
          month)(1:3)
        pos = pos + 7
      else
        print_date(pos+3:) = month(this%month)
        pos = len_trim(print_date) + 2
      end if
      write (print_date(pos:pos+3), '(i4)') &
        this%year
    end if

    return
  end function print_date

  module subroutine set_day(this, d)
    implicit none
    integer, intent (in) :: d
    class (date), intent (inout) :: this

    this%day = d
  end subroutine set_day

  module subroutine set_month(this, m)
    implicit none
    integer, intent (in) :: m
    class (date), intent (inout) :: this

    this%month = m
  end subroutine set_month

  module subroutine set_year(this, y)
    implicit none
    integer, intent (in) :: y
    class (date), intent (inout) :: this

    this%year = y
  end subroutine set_year

  module function year_and_day_to_date(year, &
    day_in_year)
    use day_and_month_name_module
    implicit none
    type (date) :: year_and_day_to_date
    integer, intent (in) :: day_in_year, year
    integer :: t
    intrinsic modulo

    year_and_day_to_date%year = year
    t = 0
    if (modulo(year,4)==0) then
      t = 1
    end if
    if (modulo(year,400)/=0 .and. &
      modulo(year,100)==0) then
      t = 0
    end if
    year_and_day_to_date%day = day_in_year
    if (day_in_year>59+t) then
      year_and_day_to_date%day = &
        year_and_day_to_date%day + 2 - t
    end if
    year_and_day_to_date%month = &
      ((year_and_day_to_date%day+91)*100)/3055
    year_and_day_to_date%day = ( &
      year_and_day_to_date%day+91) - &
      (year_and_day_to_date%month*3055)/100
    year_and_day_to_date%month = &
      year_and_day_to_date%month - 2
    if (year_and_day_to_date%month>=1 .and. &
      year_and_day_to_date%month<=12) then
      return
    end if
    write (unit=*, fmt='(a,i11,a)') &
      '$$year_and_d&
      &ay_to_date: day of the year input &
      &=', day_in_year, ' is out of range.'
  end function year_and_day_to_date

 end submodule date_module_implementation

I assume that this is an incorrect message, as the code compiles and runs with the Nag, Intel, gfortran and Cray compilers.

1 Like

Thanks Ian, though given the example is incomplete (the date_module_interface module is missing), I’m not able to compile the code and reproduce the error. Can you please post the dependent modules as well? Or better yet, a minimal reproducing example?

Apologies.

Here is a link to a web site that has all 4 source files required to compile and run
the example.

https://www.rhymneyconsulting.co.uk/fortran/nvidia/

ch3001.f90 is the driving program, and there are 3 include statements
to the other fortran source files.

Thanks Ian. I am now able to recreate the error and have filed a problem report, TPR #31598.

-Mat

Hi Ian,

FYI, TPR #31598 was fixed in the 22.11 release.

-Mat