summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-01 19:17:37 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-01 19:17:37 +0000
commitebcbc3356a31213c614cd9067a88d7b42eebe9ec (patch)
treeaca5715d2e2402e23f8d6fcb8a69bdb7516dab2e
parentb012e613100d33f9621f1a9594086450864cad13 (diff)
downloadgcc-ebcbc3356a31213c614cd9067a88d7b42eebe9ec.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100461 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog16
-rw-r--r--gcc/fortran/arith.c23
-rw-r--r--gcc/fortran/arith.h2
-rw-r--r--gcc/fortran/gfortran.texi17
-rw-r--r--gcc/fortran/intrinsic.c44
-rw-r--r--gcc/fortran/simplify.c17
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gfortran.dg/logint-1.f43
-rw-r--r--gcc/testsuite/gfortran.dg/logint-2.f43
-rw-r--r--gcc/testsuite/gfortran.dg/logint-3.f43
10 files changed, 236 insertions, 18 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f4cc96bcbd5..e7c0c95f712 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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.
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index 88b6c36e801..684ae7bfd8b 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -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;
+}
+
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index 1a718d4ea4c..f75b826ee7c 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -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 */
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 7ea59096a62..50b64990985 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -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
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 0b50cdcaa11..66cf1902689 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -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);
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index fa6c2c6aa7c..6797bcad9fa 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 716eae7cfd2..9f2246c8d15 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..d6349100860
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/logint-1.f
@@ -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
index 00000000000..a5fcf230a91
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/logint-2.f
@@ -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
index 00000000000..cf927ab8e83
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/logint-3.f
@@ -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
+