aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/simplify.c
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2015-05-10 13:56:47 +0000
committerMikael Morin <mikael@gcc.gnu.org>2015-05-10 13:56:47 +0000
commit22fa926f19ae0ebbeec9598592b0cecc9e3fcd87 (patch)
tree2cb82e13799733c3035f9753c2df8ecb70db73b6 /gcc/fortran/simplify.c
parentedff0c0662c428774cdccdab4d1998e64ce8acf5 (diff)
downloadgcc-22fa926f19ae0ebbeec9598592b0cecc9e3fcd87.zip
gcc-22fa926f19ae0ebbeec9598592b0cecc9e3fcd87.tar.gz
gcc-22fa926f19ae0ebbeec9598592b0cecc9e3fcd87.tar.bz2
bound simplification refactoring
gcc/fortran/ * simplify.c (simplify_bound_dim): Don't check for emptyness in the case of cobound simplification. Factor lower/upper bound differenciation before the actual simplification. (simplify_bound): Remove assumed shape specific simplification. Don't give up early for the lbound of an assumed shape. gcc/testsuite/ * gfortran.dg/bound_simplification_5.f90: New. From-SVN: r222979
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r--gcc/fortran/simplify.c85
1 files changed, 36 insertions, 49 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 4ef9025..f8d55fd 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -3340,29 +3340,43 @@ simplify_bound_dim (gfc_expr *array, gfc_expr *kind, int d, int upper,
/* Then, we need to know the extent of the given dimension. */
if (coarray || (ref->u.ar.type == AR_FULL && !ref->next))
{
+ gfc_expr *declared_bound;
+ int empty_bound;
+ bool constant_lbound, constant_ubound;
+
l = as->lower[d-1];
u = as->upper[d-1];
- if (l->expr_type != EXPR_CONSTANT || u == NULL
- || u->expr_type != EXPR_CONSTANT)
+ gcc_assert (l != NULL);
+
+ constant_lbound = l->expr_type == EXPR_CONSTANT;
+ constant_ubound = u && u->expr_type == EXPR_CONSTANT;
+
+ empty_bound = upper ? 0 : 1;
+ declared_bound = upper ? u : l;
+
+ if ((!upper && !constant_lbound)
+ || (upper && !constant_ubound))
goto returnNull;
- if (mpz_cmp (l->value.integer, u->value.integer) > 0)
+ if (!coarray)
{
- /* Zero extent. */
- if (upper)
- mpz_set_si (result->value.integer, 0);
+ /* For {L,U}BOUND, the value depends on whether the array
+ is empty. We can nevertheless simplify if the declared bound
+ has the same value as that of an empty array, in which case
+ the result isn't dependent on the array emptyness. */
+ if (mpz_cmp_si (declared_bound->value.integer, empty_bound) == 0)
+ mpz_set_si (result->value.integer, empty_bound);
+ else if (!constant_lbound || !constant_ubound)
+ /* Array emptyness can't be determined, we can't simplify. */
+ goto returnNull;
+ else if (mpz_cmp (l->value.integer, u->value.integer) > 0)
+ mpz_set_si (result->value.integer, empty_bound);
else
- mpz_set_si (result->value.integer, 1);
+ mpz_set (result->value.integer, declared_bound->value.integer);
}
else
- {
- /* Nonzero extent. */
- if (upper)
- mpz_set (result->value.integer, u->value.integer);
- else
- mpz_set (result->value.integer, l->value.integer);
- }
+ mpz_set (result->value.integer, declared_bound->value.integer);
}
else
{
@@ -3442,43 +3456,16 @@ simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
done:
- /* If the array shape is assumed shape or explicit, we can simplify lbound
- to 1 if the given lower bound is one because this matches what lbound
- should return for an empty array. */
-
- if (!upper && as && dim && dim->expr_type == EXPR_CONSTANT
- && (as->type == AS_ASSUMED_SHAPE || as->type == AS_EXPLICIT)
- && ref->u.ar.type != AR_SECTION)
- {
- /* Watch out for allocatable or pointer dummy arrays, they can have
- lower bounds that are not equal to one. */
- if (!(array->symtree && array->symtree->n.sym
- && (array->symtree->n.sym->attr.allocatable
- || array->symtree->n.sym->attr.pointer)))
- {
- unsigned long int ndim;
- gfc_expr *lower, *res;
-
- ndim = mpz_get_si (dim->value.integer) - 1;
- lower = as->lower[ndim];
- if (lower->expr_type == EXPR_CONSTANT
- && mpz_cmp_si (lower->value.integer, 1) == 0)
- {
- res = gfc_copy_expr (lower);
- if (kind)
- {
- int nkind = mpz_get_si (kind->value.integer);
- res->ts.kind = nkind;
- }
- return res;
- }
- }
- }
-
- if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_SHAPE
- || as->type == AS_ASSUMED_RANK))
+ if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_RANK
+ || (as->type == AS_ASSUMED_SHAPE && upper)))
return NULL;
+ gcc_assert (!as
+ || (as->type != AS_DEFERRED
+ && array->expr_type == EXPR_VARIABLE
+ && !array->symtree->n.sym->attr.allocatable
+ && !array->symtree->n.sym->attr.pointer));
+
if (dim == NULL)
{
/* Multi-dimensional bounds. */