aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSteven G. Kargl <kargl@gcc.gnu.org>2019-06-15 00:38:55 +0000
committerSteven G. Kargl <kargl@gcc.gnu.org>2019-06-15 00:38:55 +0000
commit2789efe3ee85f85ec83139fab6930cf2175be06a (patch)
tree9817f4631ecde77ff526033d2da53681378a1023 /gcc
parent4e20bd42bc04959c4b2f845352046fcfd5313484 (diff)
downloadgcc-2789efe3ee85f85ec83139fab6930cf2175be06a.zip
gcc-2789efe3ee85f85ec83139fab6930cf2175be06a.tar.gz
gcc-2789efe3ee85f85ec83139fab6930cf2175be06a.tar.bz2
arith.c (arith_power): Rework overflow of an integer to an integer exponent.
2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org> * arith.c (arith_power): Rework overflow of an integer to an integer exponent. 2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org> * gfortran.dg/integer_exponentiation_4.f90: Update test. * gfortran.dg/integer_exponentiation_5.F90: Ditto. * gfortran.dg/no_range_check_1.f90: Ditto. From-SVN: r272320
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog5
-rw-r--r--gcc/fortran/arith.c51
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gfortran.dg/integer_exponentiation_4.f908
-rw-r--r--gcc/testsuite/gfortran.dg/integer_exponentiation_5.F902
-rw-r--r--gcc/testsuite/gfortran.dg/no_range_check_1.f903
6 files changed, 43 insertions, 32 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index def1810..ddb2353 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,8 @@
+2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * arith.c (arith_power): Rework overflow of an integer to an integer
+ exponent.
+
2019-06-14 Harald Anlauf <anlauf@gmx.de>
PR fortran/90577
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index f2d311c..a4f8795 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -848,8 +848,6 @@ arith_power (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp)
{
case BT_INTEGER:
{
- int power;
-
/* First, we simplify the cases of op1 == 1, 0 or -1. */
if (mpz_cmp_si (op1->value.integer, 1) == 0)
{
@@ -884,29 +882,36 @@ arith_power (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp)
"exponent of integer has zero "
"result at %L", &result->where);
}
- else if (gfc_extract_int (op2, &power))
+ else
{
- /* If op2 doesn't fit in an int, the exponentiation will
- overflow, because op2 > 0 and abs(op1) > 1. */
- mpz_t max;
- int i;
- i = gfc_validate_kind (BT_INTEGER, result->ts.kind, false);
-
- if (flag_range_check)
- rc = ARITH_OVERFLOW;
-
- /* Still, we want to give the same value as the
- processor. */
- mpz_init (max);
- mpz_add_ui (max, gfc_integer_kinds[i].huge, 1);
- mpz_mul_ui (max, max, 2);
- mpz_powm (result->value.integer, op1->value.integer,
- op2->value.integer, max);
- mpz_clear (max);
+ /* We have abs(op1) > 1 and op2 > 1.
+ If op2 > bit_size(op1), we'll have an out-of-range
+ result. */
+ int k, power;
+
+ k = gfc_validate_kind (BT_INTEGER, op1->ts.kind, false);
+ power = gfc_integer_kinds[k].bit_size;
+ if (mpz_cmp_si (op2->value.integer, power) < 0)
+ {
+ gfc_extract_int (op2, &power);
+ mpz_pow_ui (result->value.integer, op1->value.integer,
+ power);
+ rc = gfc_range_check (result);
+ if (rc == ARITH_OVERFLOW)
+ gfc_error_now ("Result of exponentiation at %L "
+ "exceeds the range of %s", &op1->where,
+ gfc_typename (&(op1->ts)));
+ }
+ else
+ {
+ /* Provide a nonsense value to propagate up. */
+ mpz_set (result->value.integer,
+ gfc_integer_kinds[k].huge);
+ mpz_add_ui (result->value.integer,
+ result->value.integer, 1);
+ rc = ARITH_OVERFLOW;
+ }
}
- else
- mpz_pow_ui (result->value.integer, op1->value.integer,
- power);
}
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7332d53..9fc92f3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * gfortran.dg/integer_exponentiation_4.f90: Update test.
+ * gfortran.dg/integer_exponentiation_5.F90: Ditto.
+ * gfortran.dg/no_range_check_1.f90: Ditto.
+
2019-06-14 Harald Anlauf <anlauf@gmx.de>
PR fortran/90577
diff --git a/gcc/testsuite/gfortran.dg/integer_exponentiation_4.f90 b/gcc/testsuite/gfortran.dg/integer_exponentiation_4.f90
index 655f651..b224ef9 100644
--- a/gcc/testsuite/gfortran.dg/integer_exponentiation_4.f90
+++ b/gcc/testsuite/gfortran.dg/integer_exponentiation_4.f90
@@ -21,10 +21,10 @@ program test
print *, (-1)**huge(0_8)
print *, (-1)**(-huge(0_8)-1_8)
- print *, 2**huge(0) ! { dg-error "Arithmetic overflow" }
- print *, 2**huge(0_8) ! { dg-error "Arithmetic overflow" }
- print *, (-2)**huge(0) ! { dg-error "Arithmetic overflow" }
- print *, (-2)**huge(0_8) ! { dg-error "Arithmetic overflow" }
+ print *, 2**huge(0) ! { dg-error "Arithmetic overflow|exceeds the range" }
+ print *, 2**huge(0_8) ! { dg-error "Arithmetic overflow|exceeds the range" }
+ print *, (-2)**huge(0) ! { dg-error "Arithmetic overflow|exceeds the range" }
+ print *, (-2)**huge(0_8) ! { dg-error "Arithmetic overflow|exceeds the range" }
print *, 2**(-huge(0)-1)
print *, 2**(-huge(0_8)-1_8)
diff --git a/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90 b/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90
index 6069bdf..f16b751 100644
--- a/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90
+++ b/gcc/testsuite/gfortran.dg/integer_exponentiation_5.F90
@@ -67,8 +67,6 @@ program test
TEST(3_8,43_8,i8)
TEST(-3_8,43_8,i8)
- TEST(17_8,int(huge(0_4),kind=8)+1,i8)
-
!!!!! REAL BASE !!!!!
TEST(0.0,-1,r4)
TEST(0.0,-huge(0)-1,r4)
diff --git a/gcc/testsuite/gfortran.dg/no_range_check_1.f90 b/gcc/testsuite/gfortran.dg/no_range_check_1.f90
index d0bd242..7066e19 100644
--- a/gcc/testsuite/gfortran.dg/no_range_check_1.f90
+++ b/gcc/testsuite/gfortran.dg/no_range_check_1.f90
@@ -4,11 +4,8 @@
! This testcase arose from PR 31262
integer :: a
integer(kind=8) :: b
- a = -3
b = -huge(b) / 7
- a = a ** 73
b = 7894_8 * b - 78941_8
- if ((-3)**73 /= a) STOP 1
if (7894_8 * (-huge(b) / 7) - 78941_8 /= b) STOP 2
a = 1234789786453123