OSDN Git Service

2010-08-09 Thomas Koenig <tkoenig@gcc.gnu.org>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Aug 2010 19:34:49 +0000 (19:34 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Aug 2010 19:34:49 +0000 (19:34 +0000)
PR fortran/44235
* array.c (gfc_ref_dimen_size):  Add end argument.
If end is non-NULL, calculate it.
(ref_size):  Adjust call to gfc_ref_dimen_size.
(gfc_array_dimen_size):  Likewise.
(gfc_array_res_shape):  Likewise.
* gfortran.h:  Adjust prototype for gfc_ref_dimen_size.
* resolve.c (resolve_array_ref):  For stride not equal to -1,
fill in the lowest possible end.

2010-08-09  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/44235
* gfortran.dg/dependency_32.f90:  New test.

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

gcc/fortran/ChangeLog
gcc/fortran/array.c
gcc/fortran/gfortran.h
gcc/fortran/resolve.c
gcc/fortran/simplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/dependency_32.f90 [new file with mode: 0644]

index c6ef130..de7dcaf 100644 (file)
@@ -1,3 +1,15 @@
+2010-08-09  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/44235
+       * array.c (gfc_ref_dimen_size):  Add end argument.
+       If end is non-NULL, calculate it.
+       (ref_size):  Adjust call to gfc_ref_dimen_size.
+       (gfc_array_dimen_size):  Likewise.
+       (gfc_array_res_shape):  Likewise.
+       * gfortran.h:  Adjust prototype for gfc_ref_dimen_size.
+       * resolve.c (resolve_array_ref):  For stride not equal to -1,
+       fill in the lowest possible end.
+
 2010-08-09  Janus Weil  <janus@gcc.gnu.org>
 
        * intrinsic.texi: Correct documentation of ASINH, ACOSH and ATANH.
index 0d92e92..cd261bf 100644 (file)
@@ -1940,10 +1940,11 @@ spec_size (gfc_array_spec *as, mpz_t *result)
 }
 
 
-/* Get the number of elements in an array section.  */
+/* Get the number of elements in an array section. Optionally, also supply
+   the end value.  */
 
 gfc_try
-gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result)
+gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
 {
   mpz_t upper, lower, stride;
   gfc_try t;
@@ -2016,6 +2017,15 @@ gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result)
        mpz_set_ui (*result, 0);
       t = SUCCESS;
 
+      if (end)
+       {
+         mpz_init (*end);
+
+         mpz_sub_ui (*end, *result, 1UL);
+         mpz_mul (*end, *end, stride);
+         mpz_add (*end, *end, lower);
+       }
+
     cleanup:
       mpz_clear (upper);
       mpz_clear (lower);
@@ -2040,7 +2050,7 @@ ref_size (gfc_array_ref *ar, mpz_t *result)
 
   for (d = 0; d < ar->dimen; d++)
     {
-      if (gfc_ref_dimen_size (ar, d, &size) == FAILURE)
+      if (gfc_ref_dimen_size (ar, d, &size, NULL) == FAILURE)
        {
          mpz_clear (*result);
          return FAILURE;
@@ -2086,7 +2096,7 @@ gfc_array_dimen_size (gfc_expr *array, int dimen, mpz_t *result)
                if (ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
                  dimen--;
 
-             return gfc_ref_dimen_size (&ref->u.ar, i - 1, result);
+             return gfc_ref_dimen_size (&ref->u.ar, i - 1, result, NULL);
            }
        }
 
@@ -2222,7 +2232,7 @@ gfc_array_ref_shape (gfc_array_ref *ar, mpz_t *shape)
        {
          if (ar->dimen_type[i] != DIMEN_ELEMENT)
            {
-             if (gfc_ref_dimen_size (ar, i, &shape[d]) == FAILURE)
+             if (gfc_ref_dimen_size (ar, i, &shape[d], NULL) == FAILURE)
                goto cleanup;
              d++;
            }
index 713533d..898f307 100644 (file)
@@ -2753,7 +2753,7 @@ gfc_try spec_size (gfc_array_spec *, mpz_t *);
 gfc_try spec_dimen_size (gfc_array_spec *, int, mpz_t *);
 int gfc_is_compile_time_shape (gfc_array_spec *);
 
-gfc_try gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *);
+gfc_try gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *, mpz_t *);
 
 
 /* interface.c -- FIXME: some of these should be in symbol.c */
index 69a0036..9933b5d 100644 (file)
@@ -4377,6 +4377,38 @@ resolve_array_ref (gfc_array_ref *ar)
                       &ar->c_where[i], e->rank);
            return FAILURE;
          }
+
+      /* Fill in the upper bound, which may be lower than the
+        specified one for something like a(2:10:5), which is
+        identical to a(2:7:5).  Only relevant for strides not equal
+        to one.  */
+      if (ar->dimen_type[i] == DIMEN_RANGE
+         && ar->stride[i] != NULL && ar->stride[i]->expr_type == EXPR_CONSTANT
+         && mpz_cmp_si (ar->stride[i]->value.integer, 1L) != 0)
+       {
+         mpz_t size, end;
+
+         if (gfc_ref_dimen_size (ar, i, &size, &end) == SUCCESS)
+           {
+             if (ar->end[i] == NULL)
+               {
+                 ar->end[i] =
+                   gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
+                                          &ar->where);
+                 mpz_set (ar->end[i]->value.integer, end);
+               }
+             else if (ar->end[i]->ts.type == BT_INTEGER
+                      && ar->end[i]->expr_type == EXPR_CONSTANT)
+               {
+                 mpz_set (ar->end[i]->value.integer, end);
+               }
+             else
+               gcc_unreachable ();
+
+             mpz_clear (size);
+             mpz_clear (end);
+           }
+       }
     }
 
   if (ar->type == AR_FULL && ar->as->rank == 0)
index a77f6bd..b47f8cc 100644 (file)
@@ -2807,7 +2807,7 @@ simplify_bound_dim (gfc_expr *array, gfc_expr *kind, int d, int upper,
     {
       if (upper)
        {
-         if (gfc_ref_dimen_size (&ref->u.ar, d-1, &result->value.integer)
+         if (gfc_ref_dimen_size (&ref->u.ar, d-1, &result->value.integer, NULL)
              != SUCCESS)
            goto returnNull;
        }
index 93ed62f..638f3af 100644 (file)
@@ -1,3 +1,8 @@
+2010-08-09  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/44235
+       * gfortran.dg/dependency_32.f90:  New test.
+
 2010-08-09  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/44632
diff --git a/gcc/testsuite/gfortran.dg/dependency_32.f90 b/gcc/testsuite/gfortran.dg/dependency_32.f90
new file mode 100644 (file)
index 0000000..c0a3118
--- /dev/null
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-Warray-temporaries" }
+! PR 44235
+! No temporary should be created for this, as the upper bounds
+! are effectively identical.
+program main
+  real a(10)
+  a = 0.
+  a(1:10:4) = a(1:9:4)
+end program main