diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2014-04-27 10:48:56 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2014-04-27 10:48:56 +0000 |
commit | d01b2c21cf2d72c552afda7ed796c5584d11d9f3 (patch) | |
tree | df8990f63d71efb8bb9c81ebabcbf81b51cbef68 | |
parent | 0a8dbb046ca7ee236301af33d742caf85d6611b9 (diff) | |
download | gcc-d01b2c21cf2d72c552afda7ed796c5584d11d9f3.zip gcc-d01b2c21cf2d72c552afda7ed796c5584d11d9f3.tar.gz gcc-d01b2c21cf2d72c552afda7ed796c5584d11d9f3.tar.bz2 |
re PR fortran/59604 (Constant comparisons with -fno-range-check and int(z'...'))
2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/59604
PR fortran/58003
* gfortran.h (gfc_convert_mpz_to_signed): Add prototype.
* arith.c (gfc_int2int): Convert number to signed if
arithmetic overflow is not checked.
* simplify.c (convert_mpz_to_unsigned): Only trigger assert for
size if range checking is in force.
(convert_mpz_to_signed): Make non-static, rename to
(gfc_convert_mpz_to_signed).
(simplify_dshift): Use gfc_convert_mpz_to_signed.
(gfc_simplify_ibclr): Likewise.
(gfc_simplify_ibits): Likewise.
(gfc_simplify_ibset): Likewise.
(simplify_shift): Likewise.
(gfc_simplify_ishiftc): Likewise.
(gfc_simplify_maskr): Likewise.
(gfc_simplify_maskl): Likewise.
2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/59604
PR fortran/58003
* gfortran.dg/no_range_check_3.f90: New test.
From-SVN: r209836
-rw-r--r-- | gcc/fortran/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/fortran/arith.c | 11 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 4 | ||||
-rw-r--r-- | gcc/fortran/simplify.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/no_range_check_3.f90 | 12 |
6 files changed, 71 insertions, 14 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 427c9b1..5cf2513 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,23 @@ +2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/59604 + PR fortran/58003 + * gfortran.h (gfc_convert_mpz_to_signed): Add prototype. + * arith.c (gfc_int2int): Convert number to signed if + arithmetic overflow is not checked. + * simplify.c (convert_mpz_to_unsigned): Only trigger assert for + size if range checking is in force. + (convert_mpz_to_signed): Make non-static, rename to + (gfc_convert_mpz_to_signed). + (simplify_dshift): Use gfc_convert_mpz_to_signed. + (gfc_simplify_ibclr): Likewise. + (gfc_simplify_ibits): Likewise. + (gfc_simplify_ibset): Likewise. + (simplify_shift): Likewise. + (gfc_simplify_ishiftc): Likewise. + (gfc_simplify_maskr): Likewise. + (gfc_simplify_maskl): Likewise. + 2014-04-22 Tobias Burnus <burnus@net-b.de> PR fortran/60881 diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c index 053cf76..a05fa49 100644 --- a/gcc/fortran/arith.c +++ b/gcc/fortran/arith.c @@ -1976,6 +1976,17 @@ gfc_int2int (gfc_expr *src, int kind) } } + /* If we do not trap numeric overflow, we need to convert the number to + signed, throwing away high-order bits if necessary. */ + if (gfc_option.flag_range_check == 0) + { + int k; + + k = gfc_validate_kind (BT_INTEGER, kind, false); + gfc_convert_mpz_to_signed (result->value.integer, + gfc_integer_kinds[k].bit_size); + } + return result; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 14c202d..f0eed80 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3022,4 +3022,8 @@ typedef int (*walk_expr_fn_t) (gfc_expr **, int *, void *); int gfc_expr_walker (gfc_expr **, walk_expr_fn_t, void *); int gfc_code_walker (gfc_code **, walk_code_fn_t, walk_expr_fn_t, void *); +/* simplify.c */ + +void gfc_convert_mpz_to_signed (mpz_t, int); + #endif /* GCC_GFORTRAN_H */ diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 96d0f21..1b6cd5b 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -151,8 +151,10 @@ convert_mpz_to_unsigned (mpz_t x, int bitsize) if (mpz_sgn (x) < 0) { - /* Confirm that no bits above the signed range are unset. */ - gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX); + /* Confirm that no bits above the signed range are unset if we + are doing range checking. */ + if (gfc_option.flag_range_check != 0) + gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX); mpz_init_set_ui (mask, 1); mpz_mul_2exp (mask, mask, bitsize); @@ -175,13 +177,15 @@ convert_mpz_to_unsigned (mpz_t x, int bitsize) If the bitsize-1 bit is set, this is taken as a sign bit and the number is converted to the corresponding negative number. */ -static void -convert_mpz_to_signed (mpz_t x, int bitsize) +void +gfc_convert_mpz_to_signed (mpz_t x, int bitsize) { mpz_t mask; - /* Confirm that no bits above the unsigned range are set. */ - gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX); + /* Confirm that no bits above the unsigned range are set if we are + doing range checking. */ + if (gfc_option.flag_range_check != 0) + gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX); if (mpz_tstbit (x, bitsize - 1) == 1) { @@ -1943,7 +1947,7 @@ simplify_dshift (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg, mpz_setbit (result->value.integer, shift + i); /* Convert to a signed value. */ - convert_mpz_to_signed (result->value.integer, size); + gfc_convert_mpz_to_signed (result->value.integer, size); return result; } @@ -2561,7 +2565,7 @@ gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y) mpz_clrbit (result->value.integer, pos); - convert_mpz_to_signed (result->value.integer, + gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); return result; @@ -2619,7 +2623,7 @@ gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_expr *z) free (bits); - convert_mpz_to_signed (result->value.integer, + gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); return result; @@ -2646,7 +2650,7 @@ gfc_simplify_ibset (gfc_expr *x, gfc_expr *y) mpz_setbit (result->value.integer, pos); - convert_mpz_to_signed (result->value.integer, + gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); return result; @@ -3093,7 +3097,7 @@ simplify_shift (gfc_expr *e, gfc_expr *s, const char *name, } } - convert_mpz_to_signed (result->value.integer, bitsize); + gfc_convert_mpz_to_signed (result->value.integer, bitsize); free (bits); return result; @@ -3234,7 +3238,7 @@ gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz) } } - convert_mpz_to_signed (result->value.integer, isize); + gfc_convert_mpz_to_signed (result->value.integer, isize); free (bits); return result; @@ -3954,7 +3958,7 @@ gfc_simplify_maskr (gfc_expr *i, gfc_expr *kind_arg) mpz_mul_2exp (result->value.integer, result->value.integer, arg); mpz_sub_ui (result->value.integer, result->value.integer, 1); - convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); + gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); return result; } @@ -3990,7 +3994,7 @@ gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_arg) mpz_sub (result->value.integer, z, result->value.integer); mpz_clear (z); - convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); + gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size); return result; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d01d44..ba21fed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/59604 + PR fortran/58003 + * gfortran.dg/no_range_check_3.f90: New test. + 2014-04-26 Jerry DeLisle <jvdelisle@gcc.gnu> PR libfortran/52539 diff --git a/gcc/testsuite/gfortran.dg/no_range_check_3.f90 b/gcc/testsuite/gfortran.dg/no_range_check_3.f90 new file mode 100644 index 0000000..24223af --- /dev/null +++ b/gcc/testsuite/gfortran.dg/no_range_check_3.f90 @@ -0,0 +1,12 @@ +! { dg-do run } +! { dg-options "-fno-range-check" } +program test + integer :: i + i = int(z'FFFFFFFF',kind(i)) + if (i /= -1) call abort + if (int(z'FFFFFFFF',kind(i)) /= -1) call abort + + if (popcnt(int(z'0F00F00080000001',8)) /= 10) call abort + if (popcnt(int(z'800F0001',4)) /= 6) call abort + +end program test |