lfortran / lfortran

Official main repository for LFortran
https://lfortran.org/
Other
952 stars 154 forks source link

Bug in ```any``` or ```index``` instrinsic #5034

Open harperjf opened 2 weeks ago

harperjf commented 2 weeks ago

Lfortran gives an incorrect error message with this program. I don't know if the trouble is in any or in index not being elemental or even in array==scalar.

program anytest
  real,parameter:: x = 666
  character(10) cx(2)
  write(cx(1),"(E10.3)") x
  write(cx(2),"(F10.3)") x
  print *,cx
  if(any(index(cx(:),'E')==0)) print *, 'At least one cx element has no E.'
end program anytest

Lfortran 0.40.0 compile-time output omitting its Note::

semantic error: `mask` argument of `Any` intrinsic must be a logical array
 --> anytest.f90:7:10
  |
7 |   if(any(index(cx(:),'E')==0)) print *, 'At least one cx element has no E.'
  |          ^^^^^^^^^^^^^^^^^^^ 

Run-time output from any of gfortran, g95, ifx, ifort, or AMD flang:

  0.666E+03   666.000
 At least one cx element has no E.
harperjf commented 2 weeks ago

This simpler version of the program compiles, runs, and gives the wrong answer!

program anytest2
  character(5):: cx(2)=['abcd ','EFGH ']
  print *,cx
  if(any([index(cx(:),'E')==0])) then
     print *, 'At least one cx element has no E.'
  else
     print *, 'Every cx element contains an E'
  end if
end program anytest2

Run-time output with lfortran 0.40.0:

abcd     EFGH 
Every cx element contains an E

Run-time output with gfortran, g95, ifx, ifort aor AMD flang:

  abcd EFGH 
 At least one cx element has no E.
HarshitaKalani commented 2 weeks ago

There are a number of issues present here:

HarshitaKalani commented 2 weeks ago

Apart from the write format issue, it will be resolved once simplifier_pass (https://github.com/lfortran/lfortran/pull/4700) is merged.

program anytest
  real,parameter:: x = 666
  character(10) cx(2)
  cx(1) = "0.666E+03"
  cx(2) = "666.000"
  print *,cx
  print *, index(cx(:), 'E')
  print *, index(cx(:), 'E') == 0
  print *, any(index(cx(:), 'E') == 0)
  if(any(index(cx(:),'E')==0)) print *, 'At least one cx element has no E.'
end program anytest
$ lfortran a.f90
0.666E+03    666.000
6
0

F
T

T
At least one cx element has no E.
$ gfortran a.f90 && ./a.out
 0.666E+03 666.000   
           6           0
 F T
 T
 At least one cx element has no E.
jinangshah21 commented 2 weeks ago

Apart from the write format issue, it will be resolved once simplifier_pass (#4700) is merged.

program anytest
  real,parameter:: x = 666
  character(10) cx(2)
  cx(1) = "0.666E+03"
  cx(2) = "666.000"
  print *,cx
  print *, index(cx(:), 'E')
  print *, index(cx(:), 'E') == 0
  print *, any(index(cx(:), 'E') == 0)
  if(any(index(cx(:),'E')==0)) print *, 'At least one cx element has no E.'
end program anytest
$ lfortran a.f90
0.666E+03    666.000
6
0

F
T

T
At least one cx element has no E.
$ gfortran a.f90 && ./a.out
 0.666E+03 666.000   
           6           0
 F T
 T
 At least one cx element has no E.

In my local this program is not running and returns above 'mask' error.

HarshitaKalani commented 2 weeks ago

Yes Jinang, there is a PR already open (#4700) which resolves the issue. Once, it gets merged to the main, we'll not get the error anymore.

harperjf commented 2 weeks ago

You may be interested in my two programs that give properties of all the real and integer kinds available to a compiler. They are F95 and F2003 versions in https://homepages.ecs.vuw.ac.nz/~harper/fortranstuff.shtml They work with gfortran, g95, ifx, ifort and AMD flang in my Ubuntu system but they have been the reason for many of my lfortran issues. If you can't find them or think they have bugs please let me know. In particular I don't have a Microsoft or Apple system to test them in.

certik commented 2 weeks ago

Thanks! Here are direct links to the codes:

harperjf commented 2 weeks ago

I have amended both those kinds*f90 codes to explain at the end of their output what '??' implies only if it was already written somewhere.