===================================================================
@@ -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_try
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,
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 *sha
{
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++;
}
===================================================================
@@ -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 */
===================================================================
@@ -4316,6 +4316,37 @@ 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 non-zero strides. */
+ 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)
===================================================================
@@ -2807,7 +2807,7 @@ simplify_bound_dim (gfc_expr *array, gfc_expr *kin
{
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;
}