intrinsic.c (add_conv): No longer take a "simplify" argument as its always gfc_conver...
authorRoger Sayle <roger@eyesopen.com>
Wed, 1 Jun 2005 19:17:37 +0000 (19:17 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Wed, 1 Jun 2005 19:17:37 +0000 (19:17 +0000)
* intrinsic.c (add_conv): No longer take a "simplify" argument as
its always gfc_convert_constant, instead take a "standard" argument.
(add_conversions): Change all existing calls of add_conv to pass
GFC_STD_F77 as appropriate.  Additionally, if we're allowing GNU
extensions support integer-logical and logical-integer conversions.
(gfc_convert_type_warn): Warn about use the use of these conversions
as a extension when appropriate, i.e. with -pedantic.
* simplify.c (gfc_convert_constant): Add support for integer to
logical and logical to integer conversions, using gfc_int2log and
gfc_log2int.
* arith.c (gfc_log2int, gfc_int2log): New functions.
* arith.h (gfc_log2int, gfc_int2log): Prototype here.
* gfortran.texi: Document this new GNU extension.

* gfortran.dg/logint-1.f: New test case.
* gfortran.dg/logint-2.f: Likewise.
* gfortran.dg/logint-3.f: Likewise.

From-SVN: r100461

gcc/fortran/ChangeLog
gcc/fortran/arith.c
gcc/fortran/arith.h
gcc/fortran/gfortran.texi
gcc/fortran/intrinsic.c
gcc/fortran/simplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/logint-1.f [new file with mode: 0644]
gcc/testsuite/gfortran.dg/logint-2.f [new file with mode: 0644]
gcc/testsuite/gfortran.dg/logint-3.f [new file with mode: 0644]

index f4cc96bcbd5c0b132207c0ce4457e2909841dae6..e7c0c95f7124593a82dc0d14e792fb41ae610ea3 100644 (file)
@@ -1,3 +1,19 @@
+2005-06-01  Roger Sayle  <roger@eyesopen.com>
+
+       * intrinsic.c (add_conv): No longer take a "simplify" argument as
+       its always gfc_convert_constant, instead take a "standard" argument.
+       (add_conversions): Change all existing calls of add_conv to pass
+       GFC_STD_F77 as appropriate.  Additionally, if we're allowing GNU
+       extensions support integer-logical and logical-integer conversions.
+       (gfc_convert_type_warn): Warn about use the use of these conversions
+       as a extension when appropriate, i.e. with -pedantic.
+       * simplify.c (gfc_convert_constant): Add support for integer to
+       logical and logical to integer conversions, using gfc_int2log and
+       gfc_log2int.
+       * arith.c (gfc_log2int, gfc_int2log): New functions.
+       * arith.h (gfc_log2int, gfc_int2log): Prototype here.
+       * gfortran.texi: Document this new GNU extension.
+
 2005-06-01  Paul Thomas  <pault@gcc.gnu.org>
 
        * fortran/trans-expr.c (gfc_conv_variable): Clean up bracketting.
index 88b6c36e80119ee4e864b93a923aa495ae848501..684ae7bfd8be7bfb694a5aa81dddcf4b6100e519 100644 (file)
@@ -2191,3 +2191,26 @@ gfc_log2log (gfc_expr * src, int kind)
 
   return result;
 }
+
+/* Convert logical to integer.  */
+
+gfc_expr *
+gfc_log2int (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_constant_result (BT_INTEGER, kind, &src->where);
+  mpz_set_si (result->value.integer, src->value.logical);
+  return result;
+}
+
+/* Convert integer to logical.  */
+
+gfc_expr *
+gfc_int2log (gfc_expr *src, int kind)
+{
+  gfc_expr *result;
+  result = gfc_constant_result (BT_LOGICAL, kind, &src->where);
+  result->value.logical = (mpz_cmp_si (src->value.integer, 0) != 0);
+  return result;
+}
+
index 1a718d4ea4c5aaa32e7b53832246d306a6c6a29d..f75b826ee7c48baa3c09c2ad68abb8b3870ffbc4 100644 (file)
@@ -80,6 +80,8 @@ gfc_expr *gfc_complex2int (gfc_expr *, int);
 gfc_expr *gfc_complex2real (gfc_expr *, int);
 gfc_expr *gfc_complex2complex (gfc_expr *, int);
 gfc_expr *gfc_log2log (gfc_expr *, int);
+gfc_expr *gfc_log2int (gfc_expr *, int);
+gfc_expr *gfc_int2log (gfc_expr *, int);
 
 #endif /* GFC_ARITH_H  */
 
index 7ea59096a62d5c4bbfc027410cb7b2a1eaff98de..50b649909850adf8ab043cfedef4909192b74ed7 100644 (file)
@@ -637,6 +637,7 @@ of extensions, and @option{-std=legacy} allows both without warning.
 * Hexadecimal constants::
 * Real array indices::
 * Unary operators::
+* Implicitly interconvert LOGICAL and INTEGER::
 @end menu
 
 @node Old-style kind specifications
@@ -793,6 +794,22 @@ operators without the need for parenthesis.
        X = Y * -Z
 @end smallexample
 
+@node Implicitly interconvert LOGICAL and INTEGER
+@section Implicitly interconvert LOGICAL and INTEGER
+@cindex Implicitly interconvert LOGICAL and INTEGER
+
+As a GNU extension for backwards compatability 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 non-zero value is interpreted as @code{.TRUE.}.
+
+@smallexample
+       INTEGER*4 i
+       i = .FALSE.
+@end smallexample
+
 @include intrinsic.texi
 @c ---------------------------------------------------------------------
 @c Contributing
index 0b50cdcaa11151be389fd0eaea66dac98bf3e66e..66cf1902689b5d17e785eaf1c8bfae6532ae685d 100644 (file)
@@ -2227,8 +2227,7 @@ add_subroutines (void)
 /* Add a function to the list of conversion symbols.  */
 
 static void
-add_conv (bt from_type, int from_kind, bt to_type, int to_kind,
-         gfc_expr * (*simplify) (gfc_expr *, bt, int))
+add_conv (bt from_type, int from_kind, bt to_type, int to_kind, int standard)
 {
 
   gfc_typespec from, to;
@@ -2250,9 +2249,10 @@ add_conv (bt from_type, int from_kind, bt to_type, int to_kind,
 
   sym = conversion + nconv;
 
-  sym->name =  conv_name (&from, &to);
+  sym->name = conv_name (&from, &to);
   sym->lib_name = sym->name;
-  sym->simplify.cc = simplify;
+  sym->simplify.cc = gfc_convert_constant;
+  sym->standard = standard;
   sym->elemental = 1;
   sym->ts = to;
   sym->generic_id = GFC_ISYM_CONVERSION;
@@ -2277,7 +2277,7 @@ add_conversions (void)
          continue;
 
        add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
-                 BT_INTEGER, gfc_integer_kinds[j].kind, gfc_convert_constant);
+                 BT_INTEGER, gfc_integer_kinds[j].kind, GFC_STD_F77);
       }
 
   /* Integer-Real/Complex conversions.  */
@@ -2285,16 +2285,16 @@ add_conversions (void)
     for (j = 0; gfc_real_kinds[j].kind != 0; j++)
       {
        add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
-                 BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+                 BT_REAL, gfc_real_kinds[j].kind, GFC_STD_F77);
 
        add_conv (BT_REAL, gfc_real_kinds[j].kind,
-                 BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+                 BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_F77);
 
        add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
-                 BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+                 BT_COMPLEX, gfc_real_kinds[j].kind, GFC_STD_F77);
 
        add_conv (BT_COMPLEX, gfc_real_kinds[j].kind,
-                 BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+                 BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_F77);
       }
 
   /* Real/Complex - Real/Complex conversions.  */
@@ -2304,17 +2304,17 @@ add_conversions (void)
        if (i != j)
          {
            add_conv (BT_REAL, gfc_real_kinds[i].kind,
-                     BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+                     BT_REAL, gfc_real_kinds[j].kind, GFC_STD_F77);
 
            add_conv (BT_COMPLEX, gfc_real_kinds[i].kind,
-                     BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+                     BT_COMPLEX, gfc_real_kinds[j].kind, GFC_STD_F77);
          }
 
        add_conv (BT_REAL, gfc_real_kinds[i].kind,
-                 BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+                 BT_COMPLEX, gfc_real_kinds[j].kind, GFC_STD_F77);
 
        add_conv (BT_COMPLEX, gfc_real_kinds[i].kind,
-                 BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+                 BT_REAL, gfc_real_kinds[j].kind, GFC_STD_F77);
       }
 
   /* Logical/Logical kind conversion.  */
@@ -2325,8 +2325,19 @@ add_conversions (void)
          continue;
 
        add_conv (BT_LOGICAL, gfc_logical_kinds[i].kind,
-                 BT_LOGICAL, gfc_logical_kinds[j].kind, gfc_convert_constant);
+                 BT_LOGICAL, gfc_logical_kinds[j].kind, GFC_STD_F77);
       }
+
+  /* Integer-Logical and Logical-Integer conversions.  */
+  if ((gfc_option.allow_std & GFC_STD_LEGACY) != 0)
+    for (i=0; gfc_integer_kinds[i].kind; i++)
+      for (j=0; gfc_logical_kinds[j].kind; j++)
+       {
+         add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
+                   BT_LOGICAL, gfc_logical_kinds[j].kind, GFC_STD_LEGACY);
+         add_conv (BT_LOGICAL, gfc_logical_kinds[j].kind,
+                   BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
+       }
 }
 
 
@@ -3142,7 +3153,10 @@ gfc_convert_type_warn (gfc_expr * expr, gfc_typespec * ts, int eflag,
     goto bad;
 
   /* At this point, a conversion is necessary. A warning may be needed.  */
-  if (wflag && gfc_option.warn_conversion)
+  if ((gfc_option.warn_std & sym->standard) != 0)
+    gfc_warning_now ("Extension: Conversion from %s to %s at %L",
+                    gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
+  else if (wflag && gfc_option.warn_conversion)
     gfc_warning_now ("Conversion from %s to %s at %L",
                     gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
 
index fa6c2c6aa7c8708c510b06ffef953292d4fbb51f..6797bcad9fa2f3ce704031d2cc4d47befdd9e332 100644 (file)
@@ -3659,6 +3659,9 @@ gfc_convert_constant (gfc_expr * e, bt type, int kind)
        case BT_COMPLEX:
          f = gfc_int2complex;
          break;
+       case BT_LOGICAL:
+         f = gfc_int2log;
+         break;
        default:
          goto oops;
        }
@@ -3700,9 +3703,17 @@ gfc_convert_constant (gfc_expr * e, bt type, int kind)
       break;
 
     case BT_LOGICAL:
-      if (type != BT_LOGICAL)
-       goto oops;
-      f = gfc_log2log;
+      switch (type)
+       {
+       case BT_INTEGER:
+         f = gfc_log2int;
+         break;
+       case BT_LOGICAL:
+         f = gfc_log2log;
+         break;
+       default:
+         goto oops;
+       }
       break;
 
     default:
index 716eae7cfd2554baa958f8b5a95e5bfb5f92aae6..9f2246c8d1594428b83d1d1b5a890874e95b6414 100644 (file)
@@ -1,3 +1,9 @@
+2005-06-01  Roger Sayle  <roger@eyesopen.com>
+
+       * gfortran.dg/logint-1.f: New test case.
+       * gfortran.dg/logint-2.f: Likewise.
+       * gfortran.dg/logint-3.f: Likewise.
+
 2005-06-01  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/21536
diff --git a/gcc/testsuite/gfortran.dg/logint-1.f b/gcc/testsuite/gfortran.dg/logint-1.f
new file mode 100644 (file)
index 0000000..d634910
--- /dev/null
@@ -0,0 +1,43 @@
+c { dg-do compile }
+c { dg-options "-O2 -std=legacy" }
+       LOGICAL*1 l1
+       LOGICAL*2 l2
+       LOGICAL*4 l4
+       INTEGER*1 i1
+       INTEGER*2 i2
+       INTEGER*4 i4
+
+       i1 = .TRUE.
+       i2 = .TRUE.
+       i4 = .TRUE.
+
+       i1 = .FALSE.
+       i2 = .FALSE.
+       i4 = .FALSE.
+
+       i1 = l1
+       i2 = l1
+       i4 = l1
+
+       i1 = l2
+       i2 = l2
+       i4 = l2
+
+       i1 = l4
+       i2 = l4
+       i4 = l4
+
+       l1 = i1
+       l2 = i1
+       l4 = i1
+
+       l1 = i2
+       l2 = i2
+       l4 = i2
+
+       l1 = i4
+       l2 = i4
+       l4 = i4
+
+       END
diff --git a/gcc/testsuite/gfortran.dg/logint-2.f b/gcc/testsuite/gfortran.dg/logint-2.f
new file mode 100644 (file)
index 0000000..a5fcf23
--- /dev/null
@@ -0,0 +1,43 @@
+c { dg-do compile }
+c { dg-options "-O2 -std=f95" }
+       LOGICAL*1 l1
+       LOGICAL*2 l2
+       LOGICAL*4 l4
+       INTEGER*1 i1
+       INTEGER*2 i2
+       INTEGER*4 i4
+
+       i1 = .TRUE.  ! { dg-error "convert" }
+       i2 = .TRUE.  ! { dg-error "convert" }
+       i4 = .TRUE.  ! { dg-error "convert" }
+
+       i1 = .FALSE. ! { dg-error "convert" }
+       i2 = .FALSE. ! { dg-error "convert" }
+       i4 = .FALSE. ! { dg-error "convert" }
+
+       i1 = l1      ! { dg-error "convert" }
+       i2 = l1      ! { dg-error "convert" }
+       i4 = l1      ! { dg-error "convert" }
+
+       i1 = l2      ! { dg-error "convert" }
+       i2 = l2      ! { dg-error "convert" }
+       i4 = l2      ! { dg-error "convert" }
+
+       i1 = l4      ! { dg-error "convert" }
+       i2 = l4      ! { dg-error "convert" }
+       i4 = l4      ! { dg-error "convert" }
+
+       l1 = i1      ! { dg-error "convert" }
+       l2 = i1      ! { dg-error "convert" }
+       l4 = i1      ! { dg-error "convert" }
+
+       l1 = i2      ! { dg-error "convert" }
+       l2 = i2      ! { dg-error "convert" }
+       l4 = i2      ! { dg-error "convert" }
+
+       l1 = i4      ! { dg-error "convert" }
+       l2 = i4      ! { dg-error "convert" }
+       l4 = i4      ! { dg-error "convert" }
+
+       END
diff --git a/gcc/testsuite/gfortran.dg/logint-3.f b/gcc/testsuite/gfortran.dg/logint-3.f
new file mode 100644 (file)
index 0000000..cf927ab
--- /dev/null
@@ -0,0 +1,43 @@
+c { dg-do compile }
+c { dg-options "-O2" }
+       LOGICAL*1 l1
+       LOGICAL*2 l2
+       LOGICAL*4 l4
+       INTEGER*1 i1
+       INTEGER*2 i2
+       INTEGER*4 i4
+
+       i1 = .TRUE.  ! { dg-warning "Extension: Conversion" }
+       i2 = .TRUE.  ! { dg-warning "Extension: Conversion" }
+       i4 = .TRUE.  ! { dg-warning "Extension: Conversion" }
+
+       i1 = .FALSE. ! { dg-warning "Extension: Conversion" }
+       i2 = .FALSE. ! { dg-warning "Extension: Conversion" }
+       i4 = .FALSE. ! { dg-warning "Extension: Conversion" }
+
+       i1 = l1      ! { dg-warning "Extension: Conversion" }
+       i2 = l1      ! { dg-warning "Extension: Conversion" }
+       i4 = l1      ! { dg-warning "Extension: Conversion" }
+
+       i1 = l2      ! { dg-warning "Extension: Conversion" }
+       i2 = l2      ! { dg-warning "Extension: Conversion" }
+       i4 = l2      ! { dg-warning "Extension: Conversion" }
+
+       i1 = l4      ! { dg-warning "Extension: Conversion" }
+       i2 = l4      ! { dg-warning "Extension: Conversion" }
+       i4 = l4      ! { dg-warning "Extension: Conversion" }
+
+       l1 = i1      ! { dg-warning "Extension: Conversion" }
+       l2 = i1      ! { dg-warning "Extension: Conversion" }
+       l4 = i1      ! { dg-warning "Extension: Conversion" }
+
+       l1 = i2      ! { dg-warning "Extension: Conversion" }
+       l2 = i2      ! { dg-warning "Extension: Conversion" }
+       l4 = i2      ! { dg-warning "Extension: Conversion" }
+
+       l1 = i4      ! { dg-warning "Extension: Conversion" }
+       l2 = i4      ! { dg-warning "Extension: Conversion" }
+       l4 = i4      ! { dg-warning "Extension: Conversion" }
+
+       END