aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorJanus Weil <janus@gcc.gnu.org>2009-10-23 13:01:38 +0200
committerJanus Weil <janus@gcc.gnu.org>2009-10-23 13:01:38 +0200
commit8460475b4265e2a607acf6bc4bcf98bca5b38aba (patch)
treec73fa21fc6a447776ec7f36c2cb66d1bdcd615a5 /gcc/fortran/resolve.c
parente25a8c821651fdd79282b769cba179d814835666 (diff)
downloadgcc-8460475b4265e2a607acf6bc4bcf98bca5b38aba.zip
gcc-8460475b4265e2a607acf6bc4bcf98bca5b38aba.tar.gz
gcc-8460475b4265e2a607acf6bc4bcf98bca5b38aba.tar.bz2
re PR fortran/41758 ([Cleanup] Don't resolve expr in gfc_match_allocate)
2009-10-23 Janus Weil <janus@gcc.gnu.org> PR fortran/41758 * match.c (conformable_arrays): Move to resolve.c. (gfc_match_allocate): Don't resolve SOURCE expr yet, and move some checks to resolve_allocate_expr. * resolve.c (conformable_arrays): Moved here from match.c. (resolve_allocate_expr): Moved some checks here from gfc_match_allocate. (resolve_code): Resolve SOURCE tag for ALLOCATE expressions. From-SVN: r153494
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r--gcc/fortran/resolve.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 4c10a0c..b17e8fe 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -5958,6 +5958,58 @@ gfc_expr_to_initialize (gfc_expr *e)
}
+/* Used in resolve_allocate_expr to check that a allocation-object and
+ a source-expr are conformable. This does not catch all possible
+ cases; in particular a runtime checking is needed. */
+
+static gfc_try
+conformable_arrays (gfc_expr *e1, gfc_expr *e2)
+{
+ /* First compare rank. */
+ if (e2->ref && e1->rank != e2->ref->u.ar.as->rank)
+ {
+ gfc_error ("Source-expr at %L must be scalar or have the "
+ "same rank as the allocate-object at %L",
+ &e1->where, &e2->where);
+ return FAILURE;
+ }
+
+ if (e1->shape)
+ {
+ int i;
+ mpz_t s;
+
+ mpz_init (s);
+
+ for (i = 0; i < e1->rank; i++)
+ {
+ if (e2->ref->u.ar.end[i])
+ {
+ mpz_set (s, e2->ref->u.ar.end[i]->value.integer);
+ mpz_sub (s, s, e2->ref->u.ar.start[i]->value.integer);
+ mpz_add_ui (s, s, 1);
+ }
+ else
+ {
+ mpz_set (s, e2->ref->u.ar.start[i]->value.integer);
+ }
+
+ if (mpz_cmp (e1->shape[i], s) != 0)
+ {
+ gfc_error ("Source-expr at %L and allocate-object at %L must "
+ "have the same shape", &e1->where, &e2->where);
+ mpz_clear (s);
+ return FAILURE;
+ }
+ }
+
+ mpz_clear (s);
+ }
+
+ return SUCCESS;
+}
+
+
/* Resolve the expression in an ALLOCATE statement, doing the additional
checks to see whether the expression is OK or not. The expression must
have a trailing array reference that gives the size of the array. */
@@ -6057,7 +6109,32 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
return FAILURE;
}
- if (is_abstract && !code->expr3 && code->ext.alloc.ts.type == BT_UNKNOWN)
+ /* Some checks for the SOURCE tag. */
+ if (code->expr3)
+ {
+ /* Check F03:C631. */
+ if (!gfc_type_compatible (&e->ts, &code->expr3->ts))
+ {
+ gfc_error ("Type of entity at %L is type incompatible with "
+ "source-expr at %L", &e->where, &code->expr3->where);
+ return FAILURE;
+ }
+
+ /* Check F03:C632 and restriction following Note 6.18. */
+ if (code->expr3->rank > 0
+ && conformable_arrays (code->expr3, e) == FAILURE)
+ return FAILURE;
+
+ /* Check F03:C633. */
+ if (code->expr3->ts.kind != e->ts.kind)
+ {
+ gfc_error ("The allocate-object at %L and the source-expr at %L "
+ "shall have the same kind type parameter",
+ &e->where, &code->expr3->where);
+ return FAILURE;
+ }
+ }
+ else if (is_abstract&& code->ext.alloc.ts.type == BT_UNKNOWN)
{
gcc_assert (e->ts.type == BT_CLASS);
gfc_error ("Allocating %s of ABSTRACT base type at %L requires a "
@@ -7734,6 +7811,10 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
if (gfc_resolve_expr (code->expr2) == FAILURE)
t = FAILURE;
+ if (code->op == EXEC_ALLOCATE
+ && gfc_resolve_expr (code->expr3) == FAILURE)
+ t = FAILURE;
+
switch (code->op)
{
case EXEC_NOP: