diff options
author | Tobias Burnus <burnus@gcc.gnu.org> | 2007-10-14 22:24:20 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2007-10-14 22:24:20 +0200 |
commit | 1954a27b0c3d427a8fddeab6b089cbbe10f9f049 (patch) | |
tree | 672198e6c129385eba3404a760dce3a50fe15747 /gcc/fortran/resolve.c | |
parent | 2c888488e1c807f061958445b4d166c2a1040721 (diff) | |
download | gcc-1954a27b0c3d427a8fddeab6b089cbbe10f9f049.zip gcc-1954a27b0c3d427a8fddeab6b089cbbe10f9f049.tar.gz gcc-1954a27b0c3d427a8fddeab6b089cbbe10f9f049.tar.bz2 |
re PR fortran/33745 (-fbounds-check: Bogus out-of-bounds run-time error for assumed-size array)
2007-10-14 Tobias Burnus <burnus@net-b.de>
PR fortran/33745
* trans-array.c (gfc_conv_ss_startstride): Fix dimension check.
(gfc_trans_array_bound_check, gfc_conv_array_ref,
gfc_conv_ss_startstride): Simplify error message.
* resolve.c (check_dimension): Fix dimension-type switch;
improve error message.
2007-10-14 Tobias Burnus <burnus@net-b.de>
PR fortran/33745
* gfortran.dg/bounds_check_11.f90: New.
From-SVN: r129302
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 26c139c..2461bc3 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -3215,20 +3215,32 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as) /* Given start, end and stride values, calculate the minimum and maximum referenced indexes. */ - switch (ar->type) + switch (ar->dimen_type[i]) { - case AR_FULL: + case DIMEN_VECTOR: break; - case AR_ELEMENT: + case DIMEN_ELEMENT: if (compare_bound (ar->start[i], as->lower[i]) == CMP_LT) - goto bound; + { + gfc_warning ("Array reference at %L is out of bounds " + "(%ld < %ld) in dimension %d", &ar->c_where[i], + mpz_get_si (ar->start[i]->value.integer), + mpz_get_si (as->lower[i]->value.integer), i+1); + return SUCCESS; + } if (compare_bound (ar->start[i], as->upper[i]) == CMP_GT) - goto bound; + { + gfc_warning ("Array reference at %L is out of bounds " + "(%ld > %ld) in dimension %d", &ar->c_where[i], + mpz_get_si (ar->start[i]->value.integer), + mpz_get_si (as->upper[i]->value.integer), i+1); + return SUCCESS; + } break; - case AR_SECTION: + case DIMEN_RANGE: { #define AR_START (ar->start[i] ? ar->start[i] : as->lower[i]) #define AR_END (ar->end[i] ? ar->end[i] : as->upper[i]) @@ -3253,9 +3265,22 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as) || (compare_bound_int (ar->stride[i], 0) == CMP_LT && comp_start_end == CMP_GT)) { - if (compare_bound (AR_START, as->lower[i]) == CMP_LT - || compare_bound (AR_START, as->upper[i]) == CMP_GT) - goto bound; + if (compare_bound (AR_START, as->lower[i]) == CMP_LT) + { + gfc_warning ("Lower array reference at %L is out of bounds " + "(%ld < %ld) in dimension %d", &ar->c_where[i], + mpz_get_si (AR_START->value.integer), + mpz_get_si (as->lower[i]->value.integer), i+1); + return SUCCESS; + } + if (compare_bound (AR_START, as->upper[i]) == CMP_GT) + { + gfc_warning ("Lower array reference at %L is out of bounds " + "(%ld > %ld) in dimension %d", &ar->c_where[i], + mpz_get_si (AR_START->value.integer), + mpz_get_si (as->upper[i]->value.integer), i+1); + return SUCCESS; + } } /* If we can compute the highest index of the array section, @@ -3264,11 +3289,23 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as) if (compute_last_value_for_triplet (AR_START, AR_END, ar->stride[i], last_value)) { - if (compare_bound_mpz_t (as->lower[i], last_value) == CMP_GT - || compare_bound_mpz_t (as->upper[i], last_value) == CMP_LT) + if (compare_bound_mpz_t (as->lower[i], last_value) == CMP_GT) + { + gfc_warning ("Upper array reference at %L is out of bounds " + "(%ld < %ld) in dimension %d", &ar->c_where[i], + mpz_get_si (last_value), + mpz_get_si (as->lower[i]->value.integer), i+1); + mpz_clear (last_value); + return SUCCESS; + } + if (compare_bound_mpz_t (as->upper[i], last_value) == CMP_LT) { + gfc_warning ("Upper array reference at %L is out of bounds " + "(%ld > %ld) in dimension %d", &ar->c_where[i], + mpz_get_si (last_value), + mpz_get_si (as->upper[i]->value.integer), i+1); mpz_clear (last_value); - goto bound; + return SUCCESS; } } mpz_clear (last_value); @@ -3283,10 +3320,6 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as) } return SUCCESS; - -bound: - gfc_warning ("Array reference at %L is out of bounds", &ar->c_where[i]); - return SUCCESS; } |