$ cat logic.f90 program main implicit none logical(kind=4) :: lo1, lo2 integer(kind=4) :: in, i equivalence(lo1, in) do i=0,4 in = i call settrue(lo2) print *,i, lo1 , lo1 .eqv. lo2, lo1 .eqv. .true. end do end program main subroutine settrue(lo) logical(kind=4) :: lo lo = .true. end subroutine $ gfortran --std=f95 logic.f90 $ ./a.out 0 F F F 1 T T T 2 T F T 3 T F T 4 T F T $ gfortran -v Using built-in specs. Target: ia64-unknown-linux-gnu Configured with: ../gcc-4.1-20050709/configure --prefix=/home/zfkts --enable- languages=c,f95 Thread model: posix gcc version 4.1.0 20050709 (experimental) The first .eqv. is translated into a check for equality { logical4 D.573; D.573 = equiv.0.lo1 == lo2; _gfortran_transfer_logical (&D.573, 4); } the second one is removed. Do we care? Equivalencing integer and logical is prohibited (although we don't warn about this with --std=f95; maybe that is the error).
Confirmed.
I'd say we don't care. Results with other compilers: pgf90: 0 F F F 1 T F F 2 F F F 3 T F F 4 F F F ifort: 0 F F F 1 T T T 2 F F F 3 T T T 4 F F F Admittedly, there's something to be said about ifort's results :-)
Actually, the .NEQV. case would be easily fixed, as there's a TRUTH_XOR_EXPR in the middleend. On the other hand .EQV. would require adding some special case logic to gfc_conv_expr_op (admittedly, not difficult logic).
I was curious, and tried below patch, changing .EQV. to .NEQV. in the testcase, and still we don't get the "right" result, since our logical type is a real logical, in that only the lowest bit is considered. I did some checking, and our output functions seem to agree with the generated code about what values are true and what values are false, i.e. print *,i, lo1 , lo1 .eqv. lo2, lo1 .eqv. .true. if (lo1 .eqv. lo2) PRINT *, "2nd column true" if (lo1 .eqv. .true.) PRINT *, "3rd column true" would not do fancy stuff. Index: trans-expr.c =================================================================== --- trans-expr.c (revision 106379) +++ trans-expr.c (working copy) @@ -988,12 +988,17 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr break; case INTRINSIC_NE: - case INTRINSIC_NEQV: code = NE_EXPR; checkstring = 1; lop = 1; break; + case INTRINSIC_NEQV: + code = TRUTH_XOR_EXPR; + checkstring = 1; + lop = 1; + break; + case INTRINSIC_GT: code = GT_EXPR; checkstring = 1;
Hmm... in this case, I think we should document that only 0 and 1 are valid for logical types, and if the user stuffs anything else into one of our logicals, he is on his own. After we have documented this, we can close this bug as WONTFIX. Agreed?
I did some further research, and while g77 didn't seem to have documented any of the details of how LOGICALs are implemented, we have the following in gfortran.texi:755: ---- @node Implicitly interconvert LOGICAL and INTEGER @section Implicitly interconvert LOGICAL and INTEGER @cindex Implicitly interconvert LOGICAL and INTEGER As a GNU extension for backwards compatibility with other compilers, @command{gfortran} allows the implicit conversion of LOGICALs to INTEGERs and vice versa. When converting from a LOGICAL to an INTEGER, the numeric value of @code{.FALSE.} is zero, and that of @code{.TRUE.} is one. When converting from INTEGER to LOGICAL, the value zero is interpreted as @code{.FALSE.} and any nonzero value is interpreted as @code{.TRUE.}. ---- And this is indeed true and consistent with what g77 does: schluter@pcl247d:~/src/tests> cat ugly.f LOGICAL L DO i=0,5 L = i PRINT *, l END DO END schluter@pcl247d:~/src/tests> gfortran ugly.f In file ugly.f:3 L = i 1 Warning: Extension: Conversion from INTEGER(4) to LOGICAL(4) at (1) schluter@pcl247d:~/src/tests> LD_LIBRARY_PATH=~/usr/lib ./a.out F T T T T T schluter@pcl247d:~/src/tests> g77 ugly.f -fugly-logint schluter@pcl247d:~/src/tests> ./a.out F T T T T T schluter@pcl247d:~/src/tests> (The INTEGER -> LOGICAL conversion is implemented as "i = l != 0" as verified by looking in the tree dumps.) I think we should be consistent.
(In reply to comment #6) > I think we should be consistent. g77 also gives inconsistent results with the test program: $ cat logic.f program main implicit none logical :: lo1, lo2 integer :: in, i equivalence(lo1, in) do i=0,4 in = i call settrue(lo2) print *,i, lo1 , lo1 .eqv. lo2, lo1 .eqv. .true. end do end subroutine settrue(lo) logical :: lo lo = .true. end subroutine $ g77 logic.f $ ./a.out 0 F F F 1 T T T 2 T F F 3 T F F 4 T F F The test program shows that we don't currently implement the part > When > converting from INTEGER to LOGICAL, the value zero is interpreted as > @code{.FALSE.} and any nonzero value is interpreted as @code{.TRUE.}. and g77 does something else from what we do.
The code is illegal, so every compiler has produced a correct result.
One can get quite interesting results out of g77, e.g. schluter@pcl247d:~/src/tests> cat ugly.f LOGICAL L, M equivalence (i,l) DO i=0,5 M = i PRINT "(5l2)", l, m, l.neqv..true., m.neqv..true., m.neqv.l END DO END schluter@pcl247d:~/src/tests> g77 ugly.f -fugly-logint schluter@pcl247d:~/src/tests> ./a.out F F T T F T T F F F T T T T F T T T T F T T T T F T T T T F schluter@pcl247d:~/src/tests> replacing .neqv. with .eqv. on the other hand gives the "correct" result. > The test program shows that we don't currently implement the part > > > When > > converting from INTEGER to LOGICAL, the value zero is interpreted as > > @code{.FALSE.} and any nonzero value is interpreted as @code{.TRUE.}. Note that the equivalence doesn't imply conversion, so we don't contradict our documentation. Overall, given the inconsistencies in g77, and also between different other compilers, I think we shouldn't bother fixing this. I agree that adding a warning to the documentation is a good idea.
> Do we care? Equivalencing integer and logical is prohibited > (although we don't warn about this with --std=f95; maybe > that is the error). Thomas, can you point to the text in the standard that prohibits the equivalence of integer and logical. AFAICT, the 4th constraint in 5.5.1, contradicts your assertation.
(In reply to comment #10) > Thomas, can you point to the text in the standard that > prohibits the equivalence of integer and logical. AFAICT, > the 4th constraint in 5.5.1, contradicts your assertation. I was wrong there. What actually happens is that the integer value becomes undefined on assignment of the equivalenced logical, and vice versa. This still means that the program is illegal, of course.
Should we mark this as WONTFIX? I'm in favor. Thomas
WONTFIX works for me. As you originated the PR, I'll you close it.
Closing, then. Thomas