Nvfortran-22.1: wrong result for array constructor

Hi,
the following code prints a wrong result:

program p
  print *, -[ real :: +[1] ]
end
type or paste code here

With nvfortran-22.1 this prints:

-0.000000

although this should be -1.0 …

Your code is incorrect.

The intel compiler will give you an error on your original statement:
p.f90(2): error #8209: If type specification is omitted, each element in an array-constructor must have the same type and kind type parameters.
print *,-[ real:: +[1] ]
-------------------^

If you fix the code:

program p
 print *,-[ real:: +[1.] ]
end

nvfortran will give you the correct answer. But thank you for reporting, it should give you an error during compilation.

Thanks for jumping in Mass, you’re correct in that we should be giving an error here so I filed TPR#31324 and sent it to engineering for review.

-Mat

The NAG compiler accepts the code and prints the right answer.
I don’t know why Intel doesn’t see the typespec. It’s there!

Furthermore, the following variant is accepted by Intel and prints correctly while nvfortran doesn’t:

program p
  integer, parameter :: a(*) = [1]
  print *, -[ real :: a  ]
end

Intel prints:
-1.000000
nvfortran:
-0.000000

Harald

I have to agree with Harald that there is something wrong here, and I think it is a combination of an explicit type-spec and an array-valued expression. nvhpc@22.1 gets the first two of these PRINT statements correct, and then just prints a single 0.000000 for the last one:

  print *, [real:: 1,2,3]
  print *, [real:: [1,2,3]]
  print *, [real:: ([1,2,3]-[1,2,3])]

Mixing reals and integers satisfies the intrinsic assignment condition of clause 4.8.3 of the (draft) F2008 standard, so you shouldn’t need to specify the literals as reals. Comparing to ifort, it also gets the first two statements correct, but throws the error shown above on the third statement: I think it is incorrect in doing so. gfortran gets them all correct.

Paul

Also note that nvfortran produces a single 0 on this statement:

print *, [integer:: ([1,2]-[1,2])]

without any type conversion, but produces 0 0 when given

print *, [([1,2]-[1,2])]

Paul

Thanks Paul, Harold,

I did try gfortran v11.2 with the code from Harold’s original post, but it caused their f951 front-end compiler to seg fault. This with the error message given by ifort, it does seem plausible that the original version may be incorrect.

Though I don’t know this section of the standard well enough to know, so will add the additional information to the problem report and let our engineers sort things out.

For the latter examples, I agree that these do seem likely to be compiler issues.

-Mat

I also got an ICE on gfortran with the original, but if you refactor it to have only one operator (negate either the inner or outer array), it works.

My feeling is that the real problem that Harald is running into is that nvhpc is generating junk results for array-valued expressions combined with an explicit type-spec: both the size and the value of the result are wrong. I don’t think that it has anything to do with type conversion, just the explicit type-spec. In the following example, the generated executable segfaults on the last statement! If you reorder the PRINT statements, it won’t segfault, but the value is incorrect.

program	p
  print *, 'Correct: ', [([1,2,3]-[0,0,0])]
  print *, 'Bad size: ', [integer:: ([1,2,3]-[0,0,0])]

  print *, 'Correct: ', [real:: 1,2,3]
  print *, 'Correct: ', [real:: [1,2,3]]
  print *, 'Bad size & value: ', [real:: ([1,2,3]-[0,0,0])]
end program p

Note that the second REAL print statement does the conversion correctly, so I don’t believe what Intel is saying: they’re just having the same problem that nvfortran is with array-valued expressions.