Blob Blame History Raw
From 00f13a60974cb4145799593398cc61894326c222 Mon Sep 17 00:00:00 2001
From: Jim MacArthur <jim.macarthur@codethink.co.uk>
Date: Wed, 7 Oct 2015 16:31:18 -0400
Subject: [PATCH 09/23] Convert LOGICAL to INTEGER for arithmetic ops, and vice
 versa

We allow converting LOGICAL types to INTEGER when doing arithmetic
operations, and converting INTEGER types to LOGICAL for use in
boolean operations.

This feature is enabled with the `-std=extra-legacy` compiler flag.

commit f40dbd54915de8155aad94bfa19c22f11b8a8eae
Author: Jim MacArthur <jim.macarthur@codethink.co.uk>
Date:   Wed Oct 7 16:31:18 2015 -0400

    Convert LOGICAL to INTEGER for arithmetic ops, and vice versa
    
    We allow converting LOGICAL types to INTEGER when doing arithmetic
    operations, and converting INTEGER types to LOGICAL for use in
    boolean operations.
    
    This feature is enabled with the `-std=extra-legacy` compiler flag.
    
    Test written by: Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 667cc5073e3..33b441aa1bc 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -3623,6 +3623,22 @@ is_character_based (bt type)
   return type == BT_CHARACTER || type == BT_HOLLERITH;
 }
 
+/* If E is a logical, convert it to an integer and issue a warning
+   for the conversion.  */
+
+static void
+convert_integer_to_logical (gfc_expr *e)
+{
+  if (e->ts.type == BT_INTEGER)
+    {
+      /* Convert to LOGICAL */
+      gfc_typespec t;
+      t.type = BT_LOGICAL;
+      t.kind = 1;
+      gfc_convert_type_warn (e, &t, 2, 1);
+    }
+}
+
 /* If E is a logical, convert it to an integer and issue a warning
    for the conversion.  */
 
@@ -3733,6 +3749,12 @@ resolve_operator (gfc_expr *e)
     case INTRINSIC_OR:
     case INTRINSIC_EQV:
     case INTRINSIC_NEQV:
+      if (gfc_option.allow_std & GFC_STD_EXTRA_LEGACY)
+	{
+	  convert_integer_to_logical (op1);
+	  convert_integer_to_logical (op2);
+	}
+
       if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
 	{
 	  e->ts.type = BT_LOGICAL;
@@ -3774,6 +3796,11 @@ resolve_operator (gfc_expr *e)
 	  break;
 	}
 
+      if (gfc_option.allow_std & GFC_STD_EXTRA_LEGACY)
+	{
+	  convert_integer_to_logical (op1);
+	}
+
       if (op1->ts.type == BT_LOGICAL)
 	{
 	  e->ts.type = BT_LOGICAL;
diff --git a/gcc/testsuite/gfortran.dg/dec_logical_to_integer_and_vice_versa.f b/gcc/testsuite/gfortran.dg/dec_logical_to_integer_and_vice_versa.f
new file mode 100644
index 00000000000..7b9ec0d0cd2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_logical_to_integer_and_vice_versa.f
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-std=extra-legacy" }
+!
+! Test convertion between logical and integer for logical operators
+!
+        PROGRAM logical_integer_conversion
+          LOGICAL lpos /.true./
+          INTEGER ineg/0/
+          INTEGER ires
+          LOGICAL lres
+
+          ! Test Logicals converted to Integers
+          if ((lpos.AND.ineg).EQ.1) STOP 3
+          if ((ineg.AND.lpos).NE.0) STOP 4
+          ires = (.true..AND.0)
+          if (ires.NE.0) STOP 5
+          ires = (1.AND..false.)
+          if (ires.EQ.1) STOP 6
+
+          ! Test Integers converted to Logicals
+          if (lpos.EQ.ineg) STOP 7
+          if (ineg.EQ.lpos) STOP 8
+          lres = (.true..EQ.0)
+          if (lres) STOP 9
+          lres = (1.EQ..false.)
+          if (lres) STOP 10
+        END