aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/arith.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/arith.cc')
-rw-r--r--gcc/fortran/arith.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/gcc/fortran/arith.cc b/gcc/fortran/arith.cc
index 5fc9142..82a8b6f 100644
--- a/gcc/fortran/arith.cc
+++ b/gcc/fortran/arith.cc
@@ -1143,6 +1143,20 @@ arith_power (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp)
op2->value.complex, GFC_MPC_RND_MODE);
}
break;
+ case BT_UNSIGNED:
+ {
+ int k;
+ mpz_t x;
+ gcc_assert (op1->ts.type == BT_UNSIGNED);
+ k = gfc_validate_kind (BT_UNSIGNED, op1->ts.kind, false);
+ /* Exponentiation is performed modulo x = 2**n. */
+ mpz_init (x);
+ mpz_add_ui (x, gfc_unsigned_kinds[k].huge, 1);
+ mpz_powm (result->value.integer, op1->value.integer,
+ op2->value.integer, x);
+ mpz_clear (x);
+ }
+ break;
default:
gfc_internal_error ("arith_power(): unknown type");
}
@@ -1827,10 +1841,11 @@ eval_intrinsic (gfc_intrinsic_op op,
gcc_fallthrough ();
/* Numeric binary */
case INTRINSIC_POWER:
- if (flag_unsigned && op == INTRINSIC_POWER)
+ if (pedantic && (op1->ts.type == BT_UNSIGNED || op2->ts.type == BT_UNSIGNED))
{
- if (op1->ts.type == BT_UNSIGNED || op2->ts.type == BT_UNSIGNED)
- goto runtime;
+ gfc_error ("Unsigned exponentiation not permitted with -pedantic "
+ "at %L", &op1->where);
+ goto runtime;
}
gcc_fallthrough ();
@@ -1940,7 +1955,6 @@ runtime:
/* Create a run-time expression. */
result = gfc_get_operator_expr (&op1->where, op, op1, op2);
result->ts = temp.ts;
-
return result;
}