]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/46794 (ICE on valid code involving power of small integer kinds)
authorDaniel Kraft <d@domob.eu>
Thu, 9 Dec 2010 15:55:13 +0000 (16:55 +0100)
committerDaniel Kraft <domob@gcc.gnu.org>
Thu, 9 Dec 2010 15:55:13 +0000 (16:55 +0100)
2010-12-09  Daniel Kraft  <d@domob.eu>

PR fortran/46794
* trans-expr.c (gfc_conv_power_op): Handle kind of result expression
correctly for integer kind 1 and 2 operands.

2010-12-09  Daniel Kraft  <d@domob.eu>

PR fortran/46794
* gfortran.dg/power2.f90: New test.

From-SVN: r167644

gcc/fortran/ChangeLog
gcc/fortran/trans-expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/power2.f90 [new file with mode: 0644]

index 86770ae8d495ef2ab8a50ab48650c478303065d5..29c71a3b2dbdb473125bdca57c26fc1ac5519fa0 100644 (file)
@@ -1,3 +1,9 @@
+2010-12-09  Daniel Kraft  <d@domob.eu>
+
+       PR fortran/46794
+       * trans-expr.c (gfc_conv_power_op): Handle kind of result expression
+       correctly for integer kind 1 and 2 operands.
+
 2010-12-09  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/45081
index 27feea3004e70f9d9c5fda34819306f2b740183d..a68cfdcc50cefdccaec7e99732a652508d9aa26b 100644 (file)
@@ -917,6 +917,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
   tree gfc_int4_type_node;
   int kind;
   int ikind;
+  int res_ikind_1, res_ikind_2;
   gfc_se lse;
   gfc_se rse;
   tree fndecl;
@@ -937,6 +938,13 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
 
   gfc_int4_type_node = gfc_get_int_type (4);
 
+  /* In case of integer operands with kinds 1 or 2, we call the integer kind 4
+     library routine.  But in the end, we have to convert the result back
+     if this case applies -- with res_ikind_K, we keep track whether operand K
+     falls into this case.  */
+  res_ikind_1 = -1;
+  res_ikind_2 = -1;
+
   kind = expr->value.op.op1->ts.kind;
   switch (expr->value.op.op2->ts.type)
     {
@@ -947,6 +955,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
        case 1:
        case 2:
          rse.expr = convert (gfc_int4_type_node, rse.expr);
+         res_ikind_2 = ikind;
          /* Fall through.  */
 
        case 4:
@@ -969,7 +978,10 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
        case 1:
        case 2:
          if (expr->value.op.op1->ts.type == BT_INTEGER)
-           lse.expr = convert (gfc_int4_type_node, lse.expr);
+           {
+             lse.expr = convert (gfc_int4_type_node, lse.expr);
+             res_ikind_1 = kind;
+           }
          else
            gcc_unreachable ();
          /* Fall through.  */
@@ -1080,6 +1092,15 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
     }
 
   se->expr = build_call_expr (fndecl, 2, lse.expr, rse.expr);
+
+  /* Convert the result back if it is of wrong integer kind.  */
+  if (res_ikind_1 != -1 && res_ikind_2 != -1)
+    {
+      /* We want the maximum of both operand kinds as result.  */
+      if (res_ikind_1 < res_ikind_2)
+       res_ikind_1 = res_ikind_2;
+      se->expr = convert (gfc_get_int_type (res_ikind_1), se->expr);
+    }
 }
 
 
index 427920942b8a1f67ebe6eb9078e1b9cf1df8836a..ce287ab8cbad86220277fc4bade5726a0b80ce51 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-09  Daniel Kraft  <d@domob.eu>
+
+       PR fortran/46794
+       * gfortran.dg/power2.f90: New test.
+
 2010-12-09  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/45081
diff --git a/gcc/testsuite/gfortran.dg/power2.f90 b/gcc/testsuite/gfortran.dg/power2.f90
new file mode 100644 (file)
index 0000000..5e2cf04
--- /dev/null
@@ -0,0 +1,25 @@
+! { dg-do compile }
+! PR fortran/46794
+
+! Check that results of powers of integers with kinds 1 and 2 are
+! correctly converted back; this used to ICE because a conversion
+! from kind 4 to the correct one was missing.
+
+! Contributed by Daniel Kraft, d@domob.eu.
+
+PROGRAM main
+  IMPLICIT NONE
+
+  INTEGER(KIND=1) :: k1
+  INTEGER(KIND=2) :: k2
+
+  k1 = 1_1
+  k2 = 1_2
+
+  k1 = 1_1 + 1_1**k1
+  k2 = 1_2 + 1_2**k2
+
+  k2 = 1_1 + 1_1**k2
+  k2 = 1_1 + 1_2**k1
+  k2 = 1_1 + 1_2**k2
+END PROGRAM main