Internal compiler error. Deferred-length character symbol must have descriptor

I am trying to compile the following code.

module test_mod
implicit none

type fmsDiagAttribute_type
  class(*), allocatable :: att_value(:) !< Value of the attribute
  contains
  procedure :: add => fms_add_attribute
end type fmsDiagAttribute_type

contains

subroutine fms_add_attribute(this, att_value)
  class(fmsDiagAttribute_type), intent(inout) :: this !< Diag attribute type
  class(*), intent(in) :: att_value(:) !< The attribute value to add

  integer :: natt !< the size of att_value

  natt = size(att_value)
  select type (att_value)
  type is (character(len=*))
    allocate(character(len=len(att_value)) :: this%att_value(natt))
    select type(aval => this%att_value)
      type is (character(len=*))
        aval = att_value
    end select
  end select
end subroutine fms_add_attribute

end module test_mod

If I try to compile with v25.1,

$ nvfortran --version
nvfortran 25.1-0 64-bit target on x86-64 Linux -tp znver2

and I use -Mvect then I get the following error

$ nvfortran -c -Mvect test.f90 
NVFORTRAN-F-0000-Internal compiler error. Deferred-length character symbol must have descriptor     730  (test.f90: 27)
NVFORTRAN/x86-64 Linux 25.1-0: compilation aborted

Oddly, I also get this error if I try to combine -O2 with -O0.

$ nvfortran -c -O2 -O0 test.f90 
nvfortran-Info-Switch -Mvect forces -O2
NVFORTRAN-F-0000-Internal compiler error. Deferred-length character symbol must have descriptor     730  (test.f90: 27)
NVFORTRAN/x86-64 Linux 25.1-0: compilation aborted

This was discovered because I was using a wrapper that implicitly sets -O2, and I explicitly set -O0.

Adding -Mnovect also seems to have no effect.

Is this an optimization error? Or just a frontend issue with flags?

Hi Marshall,

This is an interesting one. I believe that this isn’t really a compiler bug, but rather an issue in our compiler’s configuration (“rc”) files.

Several years ago to match what other compilers were doing, we enable auto-vectorization (-Mvect) at -O2. -Mvect requires -O2 to enable the needed compiler analysis and hence the info message.

However when -Mvect is used by itself or when the -O0 is added, a key intraprocedural pointer target analysis flag isn’t getting set. Without this analysis enabled, the ICE is triggered.

I’ve submitted an issue report, TPR #37270, and will have engineering take a look at the rc files to make sure pointer target analysis is enabled with -Mvect.

The work around is to compile with just -O2, but if you must explicitly set -O0, then also add the internal flag “-Hx,53,2” to enable this analysis.

% nvfortran -c -O2 -O0 -Hx,53,2 test.f90
nvfortran-Info-Switch -Mvect forces -O2

-Mat

Thank you Mat. This magical flag appears to have fixed the compilation of this particular file. (We need -O0 during development, but we do hope to move to -O2 and -Mvect once the model is running.)

I am a little unsure what actual flags are being set here. If I do nvfortran -O2 -O0 -Hx,53,2, am I actually using -O0? Has -Mvect been enabled? Enabled then disabled?