aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/simplify.c
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <coudert@clipper.ens.fr>2006-11-16 13:25:11 +0100
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>2006-11-16 12:25:11 +0000
commit9f1dce5609ca54d2caa87d0ecfece64a7bb58c81 (patch)
treef14cc63483c17ad4c8e486eae4a98c3d88d24e41 /gcc/fortran/simplify.c
parent6c0e51c4fad90d1a93040fe92695890b5715d6f5 (diff)
downloadgcc-9f1dce5609ca54d2caa87d0ecfece64a7bb58c81.zip
gcc-9f1dce5609ca54d2caa87d0ecfece64a7bb58c81.tar.gz
gcc-9f1dce5609ca54d2caa87d0ecfece64a7bb58c81.tar.bz2
re PR fortran/29391 ([4.2/4.1 only] LBOUND and UBOUND are broken)
PR fortran/29391 PR fortran/29489 * simplify.c (simplify_bound): Fix the simplification of LBOUND/UBOUND intrinsics. * trans-intrinsic.c (simplify_bound): Fix the logic, and remove an erroneous assert. * gcc/testsuite/gfortran.dg/bound_2.f90: Add more checks. * gcc/testsuite/gfortran.dg/bound_3.f90: New test. From-SVN: r118888
Diffstat (limited to 'gcc/fortran/simplify.c')
-rw-r--r--gcc/fortran/simplify.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 75e4c3c..8ecabf0 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -1913,12 +1913,9 @@ simplify_bound (gfc_expr * array, gfc_expr * dim, int upper)
{
gfc_ref *ref;
gfc_array_spec *as;
- gfc_expr *e;
+ gfc_expr *l, *u, *result;
int d;
- if (array->expr_type != EXPR_VARIABLE)
- return NULL;
-
if (dim == NULL)
/* TODO: Simplify constant multi-dimensional bounds. */
return NULL;
@@ -1926,6 +1923,9 @@ simplify_bound (gfc_expr * array, gfc_expr * dim, int upper)
if (dim->expr_type != EXPR_CONSTANT)
return NULL;
+ if (array->expr_type != EXPR_VARIABLE)
+ return NULL;
+
/* Follow any component references. */
as = array->symtree->n.sym->as;
for (ref = array->ref; ref; ref = ref->next)
@@ -1975,12 +1975,43 @@ simplify_bound (gfc_expr * array, gfc_expr * dim, int upper)
return &gfc_bad_expr;
}
- e = upper ? as->upper[d-1] : as->lower[d-1];
+ /* The last dimension of an assumed-size array is special. */
+ if (d == as->rank && as->type == AS_ASSUMED_SIZE && !upper)
+ {
+ if (as->lower[d-1]->expr_type == EXPR_CONSTANT)
+ return gfc_copy_expr (as->lower[d-1]);
+ else
+ return NULL;
+ }
- if (e->expr_type != EXPR_CONSTANT)
+ /* Then, we need to know the extent of the given dimension. */
+ l = as->lower[d-1];
+ u = as->upper[d-1];
+
+ if (l->expr_type != EXPR_CONSTANT || u->expr_type != EXPR_CONSTANT)
return NULL;
- return gfc_copy_expr (e);
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
+ &array->where);
+
+ if (mpz_cmp (l->value.integer, u->value.integer) > 0)
+ {
+ /* Zero extent. */
+ if (upper)
+ mpz_set_si (result->value.integer, 0);
+ else
+ mpz_set_si (result->value.integer, 1);
+ }
+ else
+ {
+ /* Nonzero extent. */
+ if (upper)
+ mpz_set (result->value.integer, u->value.integer);
+ else
+ mpz_set (result->value.integer, l->value.integer);
+ }
+
+ return range_check (result, upper ? "UBOUND" : "LBOUND");
}