aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2010-12-04 10:27:17 +0100
committerDaniel Kraft <domob@gcc.gnu.org>2010-12-04 10:27:17 +0100
commit995d4d1cb5556ae6355234619cfbe187b2ec8d30 (patch)
tree22ca52b12eba47e7c8d2c8d561065cbb8a2309cb /gcc
parent9b2b801af5011d6b1f92899f682107776019766c (diff)
downloadgcc-995d4d1cb5556ae6355234619cfbe187b2ec8d30.zip
gcc-995d4d1cb5556ae6355234619cfbe187b2ec8d30.tar.gz
gcc-995d4d1cb5556ae6355234619cfbe187b2ec8d30.tar.bz2
re PR fortran/46794 (ICE on valid code involving power of small integer kinds)
2010-12-04 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-04 Daniel Kraft <d@domob.eu> PR fortran/46794 * gfortran.dg/power2.f90: New test. From-SVN: r167453
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-expr.c23
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/power2.f9022
4 files changed, 55 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 99c82d2..a1d06c5 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2010-12-04 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-03 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/44352
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 5857c0d..46f80f7 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -976,6 +976,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 = NULL;
@@ -996,6 +997,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)
{
@@ -1006,6 +1014,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:
@@ -1028,7 +1037,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. */
@@ -1121,6 +1133,15 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
se->expr = build_call_expr_loc (input_location,
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);
+ }
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f46c555..e48bf78 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-12-04 Daniel Kraft <d@domob.eu>
+
+ PR fortran/46794
+ * gfortran.dg/power2.f90: New test.
+
2010-12-03 Jakub Jelinek <jakub@redhat.com>
PR debug/46123
diff --git a/gcc/testsuite/gfortran.dg/power2.f90 b/gcc/testsuite/gfortran.dg/power2.f90
new file mode 100644
index 0000000..01954cb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/power2.f90
@@ -0,0 +1,22 @@
+! { 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 + 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