]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR fortran/30655
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 24 Mar 2007 20:19:51 +0000 (20:19 +0000)
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 24 Mar 2007 20:19:51 +0000 (20:19 +0000)
* expr.c (check_dimension): Fix logic of comparisons.

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123187 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/resolve.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/bounds_check_6.f90 [new file with mode: 0644]

index 99c67fc6764a9209e2571edc540df9346c09875a..d99b31f567ac0bd3758250daf968bc2652bd0086 100644 (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
index a72047e3ffb7ef0f7e1dec18294e7e7fd1025470..164a0cb9020addf605fb772295f2917fe0d68938 100644 (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:
index 39365b756b54a07d1b210bfd1f3173032133bee8..e8650e49b7989a8e910fe852261c84be80da31cb 100644 (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
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_6.f90 b/gcc/testsuite/gfortran.dg/bounds_check_6.f90
new file mode 100644 (file)
index 0000000..6535db7
--- /dev/null
@@ -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