static void
evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
- tree desc, int dim, bool lbound)
+ tree desc, int dim, bool lbound, bool deferred)
{
gfc_se se;
gfc_expr * input_val = values[dim];
gfc_add_block_to_block (block, &se.pre);
*output = se.expr;
}
+ else if (deferred)
+ {
+ /* The gfc_conv_array_lbound () routine returns a constant zero for
+ deferred length arrays, which in the scalarizer wrecks havoc, when
+ copying to a (newly allocated) one-based array.
+ Keep returning the actual result in sync for both bounds. */
+ *output = lbound ? gfc_conv_descriptor_lbound_get (desc,
+ gfc_rank_cst[dim]):
+ gfc_conv_descriptor_ubound_get (desc,
+ gfc_rank_cst[dim]);
+ }
else
{
/* No specific bound specified so use the bound of the array. */
desc = info->descriptor;
stride = ar->stride[dim];
+
/* Calculate the start of the range. For vector subscripts this will
be the range of the vector. */
- evaluate_bound (block, info->start, ar->start, desc, dim, true);
+ evaluate_bound (block, info->start, ar->start, desc, dim, true,
+ ar->as->type == AS_DEFERRED);
/* Similarly calculate the end. Although this is not used in the
scalarizer, it is needed when checking bounds and where the end
is an expression with side-effects. */
- evaluate_bound (block, info->end, ar->end, desc, dim, false);
+ evaluate_bound (block, info->end, ar->end, desc, dim, false,
+ ar->as->type == AS_DEFERRED);
+
/* Calculate the stride. */
if (stride == NULL)
gcc_assert (n == codim - 1);
evaluate_bound (&loop.pre, info->start, ar->start,
- info->descriptor, n + ndim, true);
+ info->descriptor, n + ndim, true,
+ ar->as->type == AS_DEFERRED);
loop.from[n + loop.dimen] = info->start[n + ndim];
}
else