diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a286bcdcdca..a80892600a8 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,4 +1,12 @@ -2006-09-05 Paul Thomas +2006-09-07 Steven G. Kargl + + * gfortran.h (gfc_integer_info): Eliminate max_int. + * arith.c (gfc_arith_init_1): Remove initialization of max_int. + (gfc_arith_done_1): Remove clearing of max_int. + (gfc_check_integer_range): Fix range chekcing of overflow. + * simplify.c (gfc_simplify_not): Construct mask that was max_int. + +2006-09-05 Paul Thomas PR fortran/28908 * gfortran.h : Restore the gfc_dt_list structure and reference diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c index 884d810c99b..766169fa6e1 100644 --- a/gcc/fortran/arith.c +++ b/gcc/fortran/arith.c @@ -195,7 +195,7 @@ gfc_arith_init_1 (void) /* These are the numbers that are actually representable by the target. For bases other than two, this needs to be changed. */ if (int_info->radix != 2) - gfc_internal_error ("Fix min_int, max_int calculation"); + gfc_internal_error ("Fix min_int calculation"); /* See PRs 13490 and 17912, related to integer ranges. The pedantic_min_int exists for range checking when a program @@ -210,10 +210,6 @@ gfc_arith_init_1 (void) mpz_init (int_info->min_int); mpz_sub_ui (int_info->min_int, int_info->pedantic_min_int, 1); - mpz_init (int_info->max_int); - mpz_add (int_info->max_int, int_info->huge, int_info->huge); - mpz_add_ui (int_info->max_int, int_info->max_int, 1); - /* Range */ mpfr_set_z (a, int_info->huge, GFC_RND_MODE); mpfr_log10 (a, a, GFC_RND_MODE); @@ -321,7 +317,6 @@ gfc_arith_done_1 (void) for (ip = gfc_integer_kinds; ip->kind; ip++) { mpz_clear (ip->min_int); - mpz_clear (ip->max_int); mpz_clear (ip->pedantic_min_int); mpz_clear (ip->huge); } @@ -356,7 +351,7 @@ gfc_check_integer_range (mpz_t p, int kind) } if (mpz_cmp (p, gfc_integer_kinds[i].min_int) < 0 - || mpz_cmp (p, gfc_integer_kinds[i].max_int) > 0) + || mpz_cmp (p, gfc_integer_kinds[i].huge) > 0) result = ARITH_OVERFLOW; return result; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 01bcf976e54..60a53335cfb 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1299,7 +1299,7 @@ gfc_expr; typedef struct { /* Values really representable by the target. */ - mpz_t huge, pedantic_min_int, min_int, max_int; + mpz_t huge, pedantic_min_int, min_int; int kind, radix, digits, bit_size, range; diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 8a7d79b4df6..48d8e6beab9 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -2590,6 +2590,7 @@ gfc_simplify_not (gfc_expr * e) { gfc_expr *result; int i; + mpz_t mask; if (e->expr_type != EXPR_CONSTANT) return NULL; @@ -2599,15 +2600,20 @@ gfc_simplify_not (gfc_expr * e) mpz_com (result->value.integer, e->value.integer); /* Because of how GMP handles numbers, the result must be ANDed with - the max_int mask. For radices <> 2, this will require change. */ + a mask. For radices <> 2, this will require change. */ i = gfc_validate_kind (BT_INTEGER, e->ts.kind, false); - mpz_and (result->value.integer, result->value.integer, - gfc_integer_kinds[i].max_int); + mpz_init (mask); + mpz_add (mask, gfc_integer_kinds[i].huge, gfc_integer_kinds[i].huge); + mpz_add_ui (mask, mask, 1); + + mpz_and (result->value.integer, result->value.integer, mask); twos_complement (result->value.integer, gfc_integer_kinds[i].bit_size); + mpz_clear (mask); + return range_check (result, "NOT"); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5e629d6fad6..86794ebf5d9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-09-07 Steven G. Kargl + + * gfortran.fortran-torture/compile/data_1.f90: Fix integer oveflow + in integer literal constant. + * gfortran.dg/enum_8.f90: Ditto. + * gfortran.dg/g77/20030326-1.f: Ditto. + 2006-09-07 Feng Wang * gfortran.fortran-torture/execute/intrinsic_set_exponent.f90: Fix diff --git a/gcc/testsuite/gfortran.dg/enum_8.f90 b/gcc/testsuite/gfortran.dg/enum_8.f90 index cd3c12a27f7..819c5870801 100644 --- a/gcc/testsuite/gfortran.dg/enum_8.f90 +++ b/gcc/testsuite/gfortran.dg/enum_8.f90 @@ -5,7 +5,7 @@ program main implicit none enum, bind (c) - enumerator :: pp , qq = 4294967295, rr ! { dg-error "not initialized with integer" } + enumerator :: pp, qq = 4294967295, rr ! { dg-error "too big for its kind" } end enum ! { dg-error "has no ENUMERATORS" } enum, bind (c) diff --git a/gcc/testsuite/gfortran.dg/g77/20030326-1.f b/gcc/testsuite/gfortran.dg/g77/20030326-1.f index dc4ff43cd47..4741fd7888c 100644 --- a/gcc/testsuite/gfortran.dg/g77/20030326-1.f +++ b/gcc/testsuite/gfortran.dg/g77/20030326-1.f @@ -6,5 +6,5 @@ ! For gfortran, see PR 13490 ! integer c - c = -2147483648 / (-1) ! { dg-warning "outside symmetric range" "" } + c = -2147483648 / (-1) ! { dg-error "too big for its kind" "" } end diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/data_1.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/data_1.f90 index e3d65efc520..b283909931d 100644 --- a/gcc/testsuite/gfortran.fortran-torture/compile/data_1.f90 +++ b/gcc/testsuite/gfortran.fortran-torture/compile/data_1.f90 @@ -7,5 +7,5 @@ DATA y /a(1.)/ ! used to give an error about non-PARAMETER END ! this tests the fix for PR 13940 SUBROUTINE a -DATA i /x'f95f95f9'/ +DATA i /z'f95f95'/ END