Blame SOURCES/0009-Convert-LOGICAL-to-INTEGER-for-arithmetic-ops-and-vi.patch

840d93
From 00f13a60974cb4145799593398cc61894326c222 Mon Sep 17 00:00:00 2001
840d93
From: Jim MacArthur <jim.macarthur@codethink.co.uk>
840d93
Date: Wed, 7 Oct 2015 16:31:18 -0400
840d93
Subject: [PATCH 09/23] Convert LOGICAL to INTEGER for arithmetic ops, and vice
840d93
 versa
840d93
840d93
We allow converting LOGICAL types to INTEGER when doing arithmetic
840d93
operations, and converting INTEGER types to LOGICAL for use in
840d93
boolean operations.
840d93
840d93
This feature is enabled with the `-std=extra-legacy` compiler flag.
840d93
840d93
commit f40dbd54915de8155aad94bfa19c22f11b8a8eae
840d93
Author: Jim MacArthur <jim.macarthur@codethink.co.uk>
840d93
Date:   Wed Oct 7 16:31:18 2015 -0400
840d93
840d93
    Convert LOGICAL to INTEGER for arithmetic ops, and vice versa
840d93
    
840d93
    We allow converting LOGICAL types to INTEGER when doing arithmetic
840d93
    operations, and converting INTEGER types to LOGICAL for use in
840d93
    boolean operations.
840d93
    
840d93
    This feature is enabled with the `-std=extra-legacy` compiler flag.
840d93
    
840d93
    Test written by: Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
840d93
840d93
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
840d93
index 667cc5073e3..33b441aa1bc 100644
840d93
--- a/gcc/fortran/resolve.c
840d93
+++ b/gcc/fortran/resolve.c
840d93
@@ -3623,6 +3623,22 @@ is_character_based (bt type)
840d93
   return type == BT_CHARACTER || type == BT_HOLLERITH;
840d93
 }
840d93
 
840d93
+/* If E is a logical, convert it to an integer and issue a warning
840d93
+   for the conversion.  */
840d93
+
840d93
+static void
840d93
+convert_integer_to_logical (gfc_expr *e)
840d93
+{
840d93
+  if (e->ts.type == BT_INTEGER)
840d93
+    {
840d93
+      /* Convert to LOGICAL */
840d93
+      gfc_typespec t;
840d93
+      t.type = BT_LOGICAL;
840d93
+      t.kind = 1;
840d93
+      gfc_convert_type_warn (e, &t, 2, 1);
840d93
+    }
840d93
+}
840d93
+
840d93
 /* If E is a logical, convert it to an integer and issue a warning
840d93
    for the conversion.  */
840d93
 
840d93
@@ -3733,6 +3749,12 @@ resolve_operator (gfc_expr *e)
840d93
     case INTRINSIC_OR:
840d93
     case INTRINSIC_EQV:
840d93
     case INTRINSIC_NEQV:
840d93
+      if (gfc_option.allow_std & GFC_STD_EXTRA_LEGACY)
840d93
+	{
840d93
+	  convert_integer_to_logical (op1);
840d93
+	  convert_integer_to_logical (op2);
840d93
+	}
840d93
+
840d93
       if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
840d93
 	{
840d93
 	  e->ts.type = BT_LOGICAL;
840d93
@@ -3774,6 +3796,11 @@ resolve_operator (gfc_expr *e)
840d93
 	  break;
840d93
 	}
840d93
 
840d93
+      if (gfc_option.allow_std & GFC_STD_EXTRA_LEGACY)
840d93
+	{
840d93
+	  convert_integer_to_logical (op1);
840d93
+	}
840d93
+
840d93
       if (op1->ts.type == BT_LOGICAL)
840d93
 	{
840d93
 	  e->ts.type = BT_LOGICAL;
840d93
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
840d93
new file mode 100644
840d93
index 00000000000..7b9ec0d0cd2
840d93
--- /dev/null
840d93
+++ b/gcc/testsuite/gfortran.dg/dec_logical_to_integer_and_vice_versa.f
840d93
@@ -0,0 +1,27 @@
840d93
+! { dg-do compile }
840d93
+! { dg-options "-std=extra-legacy" }
840d93
+!
840d93
+! Test convertion between logical and integer for logical operators
840d93
+!
840d93
+        PROGRAM logical_integer_conversion
840d93
+          LOGICAL lpos /.true./
840d93
+          INTEGER ineg/0/
840d93
+          INTEGER ires
840d93
+          LOGICAL lres
840d93
+
840d93
+          ! Test Logicals converted to Integers
840d93
+          if ((lpos.AND.ineg).EQ.1) STOP 3
840d93
+          if ((ineg.AND.lpos).NE.0) STOP 4
840d93
+          ires = (.true..AND.0)
840d93
+          if (ires.NE.0) STOP 5
840d93
+          ires = (1.AND..false.)
840d93
+          if (ires.EQ.1) STOP 6
840d93
+
840d93
+          ! Test Integers converted to Logicals
840d93
+          if (lpos.EQ.ineg) STOP 7
840d93
+          if (ineg.EQ.lpos) STOP 8
840d93
+          lres = (.true..EQ.0)
840d93
+          if (lres) STOP 9
840d93
+          lres = (1.EQ..false.)
840d93
+          if (lres) STOP 10
840d93
+        END