re PR fortran/30655 (Undue out-of-bounds warning)

PR fortran/30655

	* expr.c (check_dimension): Fix logic of comparisons.

	* gfortran.dg/bounds_check_6.f90: New test.

From-SVN: r123187
This commit is contained in:
Francois-Xavier Coudert 2007-03-24 20:19:51 +00:00 committed by François-Xavier Coudert
parent 13f703423a
commit d912240d90
4 changed files with 56 additions and 33 deletions

View File

@ -1,3 +1,8 @@
2007-03-24 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/30655
* expr.c (check_dimension): Fix logic of comparisons.
2007-03-24 Paul Thomas <pault@gcc.gnu.org>
PR fortran/31215

View File

@ -2507,48 +2507,53 @@ check_dimension (int i, gfc_array_ref *ar, gfc_array_spec *as)
break;
case AR_SECTION:
if (compare_bound_int (ar->stride[i], 0) == CMP_EQ)
{
gfc_error ("Illegal stride of zero at %L", &ar->c_where[i]);
return FAILURE;
}
{
#define AR_START (ar->start[i] ? ar->start[i] : as->lower[i])
#define AR_END (ar->end[i] ? ar->end[i] : as->upper[i])
if (compare_bound (AR_START, AR_END) == CMP_EQ
&& (compare_bound (AR_START, as->lower[i]) == CMP_LT
|| compare_bound (AR_START, as->upper[i]) == CMP_GT))
goto bound;
comparison comp_start_end = compare_bound (AR_START, AR_END);
if (((compare_bound_int (ar->stride[i], 0) == CMP_GT
|| ar->stride[i] == NULL)
&& compare_bound (AR_START, AR_END) != CMP_GT)
|| (compare_bound_int (ar->stride[i], 0) == CMP_LT
&& compare_bound (AR_START, AR_END) != CMP_LT))
{
if (compare_bound (AR_START, as->lower[i]) == CMP_LT)
goto bound;
if (compare_bound (AR_START, as->upper[i]) == CMP_GT)
goto bound;
}
/* Check for zero stride, which is not allowed. */
if (compare_bound_int (ar->stride[i], 0) == CMP_EQ)
{
gfc_error ("Illegal stride of zero at %L", &ar->c_where[i]);
return FAILURE;
}
mpz_init (last_value);
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)
{
mpz_clear (last_value);
/* if start == len || (stride > 0 && start < len)
|| (stride < 0 && start > len),
then the array section contains at least one element. In this
case, there is an out-of-bounds access if
(start < lower || start > upper). */
if (compare_bound (AR_START, AR_END) == CMP_EQ
|| ((compare_bound_int (ar->stride[i], 0) == CMP_GT
|| ar->stride[i] == NULL) && comp_start_end == CMP_LT)
|| (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;
}
}
mpz_clear (last_value);
}
/* If we can compute the highest index of the array section,
then it also has to be between lower and upper. */
mpz_init (last_value);
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)
{
mpz_clear (last_value);
goto bound;
}
}
mpz_clear (last_value);
#undef AR_START
#undef AR_END
}
break;
default:

View File

@ -1,3 +1,8 @@
2007-03-24 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/30655
* gfortran.dg/bounds_check_6.f90: New test.
2007-03-23 Michael Meissner <michael.meissner@amd.com>
* gcc.dg/dfp/convert-dfp.c: Wrap __STDC_WANT_DEC_FP__ with

View File

@ -0,0 +1,8 @@
! { dg-do run }
! { dg-options "-fbounds-check" }
!
! Testcase for PR30655, we used to issue a compile-time warning
integer i(12), j
j = -1
i(0:j) = 42
end