Bug 22495 - Different ideas about .true. and .false.
Summary: Different ideas about .true. and .false.
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: documentation
Depends on:
Blocks:
 
Reported: 2005-07-15 08:46 UTC by Thomas Koenig
Modified: 2006-01-30 06:44 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-11-06 00:32:32


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2005-07-15 08:46:40 UTC
$ 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).
Comment 1 Andrew Pinski 2005-07-15 22:19:36 UTC
Confirmed.
Comment 2 Tobias Schlüter 2005-11-01 21:30:39 UTC
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 :-)
Comment 3 Tobias Schlüter 2005-11-01 21:36:21 UTC
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).
Comment 4 Tobias Schlüter 2005-11-02 12:37:37 UTC
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;
Comment 5 Thomas Koenig 2005-11-05 22:05:14 UTC
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?
Comment 6 Tobias Schlüter 2005-11-05 23:06:17 UTC
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.
Comment 7 Thomas Koenig 2005-11-05 23:20:26 UTC
(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.
Comment 8 kargls 2005-11-06 00:02:03 UTC
The code is illegal, so every compiler has produced a
correct result.
Comment 9 Tobias Schlüter 2005-11-06 00:22:18 UTC
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.
Comment 10 kargls 2005-11-06 00:32:32 UTC
> 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.

Comment 11 Thomas Koenig 2005-11-06 15:01:46 UTC
(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.
Comment 12 Thomas Koenig 2006-01-29 23:30:03 UTC
Should we mark this as WONTFIX?

I'm in favor.

Thomas
Comment 13 kargls 2006-01-30 00:52:06 UTC
WONTFIX works for me.  As you originated the PR, I'll you close it.
Comment 14 Thomas Koenig 2006-01-30 06:44:55 UTC
Closing, then.

Thomas