summaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2008-02-03 11:29:27 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2008-02-03 11:29:27 +0000
commita9e7fd6a16ffdbec685fac893dd44f1831849cc1 (patch)
tree730852770e905aafbbe0906c5de87169a2ad6c36 /gcc/fortran
parent4166e2c81ae7bf81b73aeb0a3cd00ae4d1b83aa9 (diff)
downloadgcc-a9e7fd6a16ffdbec685fac893dd44f1831849cc1.tar.gz
2008-02-03 Paul Thomas <pault@gcc.gnu.org>
PR fortran/32760 * resolve.c (resolve_allocate_deallocate): New function. (resolve_code): Call it for allocate and deallocate. * match.c (gfc_match_allocate, gfc_match_deallocate) : Remove the checking of the STAT tag and put in above new function. * primary,c (match_variable): Do not fix flavor of host associated symbols yet if the type is not known. 2008-02-03 Paul Thomas <pault@gcc.gnu.org> PR fortran/32760 * gfortran.dg/host_assoc_variable_1.f90: New test. * gfortran.dg/allocate_stat.f90: Change last three error messages. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132078 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog10
-rw-r--r--gcc/fortran/match.c81
-rw-r--r--gcc/fortran/primary.c8
-rw-r--r--gcc/fortran/resolve.c95
4 files changed, 99 insertions, 95 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index f426aa24059..33f342391af 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,13 @@
+2008-02-03 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/32760
+ * resolve.c (resolve_allocate_deallocate): New function.
+ (resolve_code): Call it for allocate and deallocate.
+ * match.c (gfc_match_allocate, gfc_match_deallocate) : Remove
+ the checking of the STAT tag and put in above new function.
+ * primary,c (match_variable): Do not fix flavor of host
+ associated symbols yet if the type is not known.
+
2008-01-31 Paul Thomas <pault@gcc.gnu.org>
PR fortran/34910
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index ad636f93f3d..324e52ecee0 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2235,62 +2235,7 @@ gfc_match_allocate (void)
}
if (stat != NULL)
- {
- bool is_variable;
-
- if (stat->symtree->n.sym->attr.intent == INTENT_IN)
- {
- gfc_error ("STAT variable '%s' of ALLOCATE statement at %C cannot "
- "be INTENT(IN)", stat->symtree->n.sym->name);
- goto cleanup;
- }
-
- if (gfc_pure (NULL) && gfc_impure_variable (stat->symtree->n.sym))
- {
- gfc_error ("Illegal STAT variable in ALLOCATE statement at %C "
- "for a PURE procedure");
- goto cleanup;
- }
-
- is_variable = false;
- if (stat->symtree->n.sym->attr.flavor == FL_VARIABLE)
- is_variable = true;
- else if (stat->symtree->n.sym->attr.function
- && stat->symtree->n.sym->result == stat->symtree->n.sym
- && (gfc_current_ns->proc_name == stat->symtree->n.sym
- || (gfc_current_ns->parent
- && gfc_current_ns->parent->proc_name
- == stat->symtree->n.sym)))
- is_variable = true;
- else if (gfc_current_ns->entries
- && stat->symtree->n.sym->result == stat->symtree->n.sym)
- {
- gfc_entry_list *el;
- for (el = gfc_current_ns->entries; el; el = el->next)
- if (el->sym == stat->symtree->n.sym)
- {
- is_variable = true;
- }
- }
- else if (gfc_current_ns->parent && gfc_current_ns->parent->entries
- && stat->symtree->n.sym->result == stat->symtree->n.sym)
- {
- gfc_entry_list *el;
- for (el = gfc_current_ns->parent->entries; el; el = el->next)
- if (el->sym == stat->symtree->n.sym)
- {
- is_variable = true;
- }
- }
-
- if (!is_variable)
- {
- gfc_error ("STAT expression at %C must be a variable");
- goto cleanup;
- }
-
- gfc_check_do_variable(stat->symtree);
- }
+ gfc_check_do_variable(stat->symtree);
if (gfc_match (" )%t") != MATCH_YES)
goto syntax;
@@ -2432,29 +2377,7 @@ gfc_match_deallocate (void)
}
if (stat != NULL)
- {
- if (stat->symtree->n.sym->attr.intent == INTENT_IN)
- {
- gfc_error ("STAT variable '%s' of DEALLOCATE statement at %C "
- "cannot be INTENT(IN)", stat->symtree->n.sym->name);
- goto cleanup;
- }
-
- if (gfc_pure(NULL) && gfc_impure_variable (stat->symtree->n.sym))
- {
- gfc_error ("Illegal STAT variable in DEALLOCATE statement at %C "
- "for a PURE procedure");
- goto cleanup;
- }
-
- if (stat->symtree->n.sym->attr.flavor != FL_VARIABLE)
- {
- gfc_error ("STAT expression at %C must be a variable");
- goto cleanup;
- }
-
- gfc_check_do_variable(stat->symtree);
- }
+ gfc_check_do_variable(stat->symtree);
if (gfc_match (" )%t") != MATCH_YES)
goto syntax;
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 1895ca07f56..8385cb5788e 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2534,6 +2534,14 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
if (sym->attr.external || sym->attr.procedure
|| sym->attr.function || sym->attr.subroutine)
flavor = FL_PROCEDURE;
+
+ /* If it is not a procedure, is not typed and is host associated,
+ we cannot give it a flavor yet. */
+ else if (sym->ns == gfc_current_ns->parent
+ && sym->ts.type == BT_UNKNOWN)
+ break;
+
+ /* These are definitive indicators that this is a variable. */
else if (gfc_peek_char () != '(' || sym->ts.type != BT_UNKNOWN
|| sym->attr.pointer || sym->as != NULL)
flavor = FL_VARIABLE;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 833fd27611c..926f0455f48 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -4864,6 +4864,81 @@ check_symbols:
return SUCCESS;
}
+static void
+resolve_allocate_deallocate (gfc_code *code, const char *fcn)
+{
+ gfc_symbol *s = NULL;
+ gfc_alloc *a;
+ bool is_variable;
+
+ if (code->expr)
+ s = code->expr->symtree->n.sym;
+
+ if (s)
+ {
+ if (s->attr.intent == INTENT_IN)
+ gfc_error ("STAT variable '%s' of %s statement at %C cannot "
+ "be INTENT(IN)", s->name, fcn);
+
+ if (gfc_pure (NULL) && gfc_impure_variable (s))
+ gfc_error ("Illegal STAT variable in %s statement at %C "
+ "for a PURE procedure", fcn);
+
+ is_variable = false;
+ if (s->attr.flavor == FL_VARIABLE)
+ is_variable = true;
+ else if (s->attr.function && s->result == s
+ && (gfc_current_ns->proc_name == s
+ ||
+ (gfc_current_ns->parent
+ && gfc_current_ns->parent->proc_name == s)))
+ is_variable = true;
+ else if (gfc_current_ns->entries && s->result == s)
+ {
+ gfc_entry_list *el;
+ for (el = gfc_current_ns->entries; el; el = el->next)
+ if (el->sym == s)
+ {
+ is_variable = true;
+ }
+ }
+ else if (gfc_current_ns->parent && gfc_current_ns->parent->entries
+ && s->result == s)
+ {
+ gfc_entry_list *el;
+ for (el = gfc_current_ns->parent->entries; el; el = el->next)
+ if (el->sym == s)
+ {
+ is_variable = true;
+ }
+ }
+
+ if (s->attr.flavor == FL_UNKNOWN
+ && gfc_add_flavor (&s->attr, FL_VARIABLE,
+ s->name, NULL) == SUCCESS)
+ is_variable = true;
+
+ if (!is_variable)
+ gfc_error ("STAT tag in %s statement at %L must be "
+ "a variable", fcn, &code->expr->where);
+
+ }
+
+ if (s && code->expr->ts.type != BT_INTEGER)
+ gfc_error ("STAT tag in %s statement at %L must be "
+ "of type INTEGER", fcn, &code->expr->where);
+
+ if (strcmp (fcn, "ALLOCATE") == 0)
+ {
+ for (a = code->ext.alloc_list; a; a = a->next)
+ resolve_allocate_expr (a->expr, code);
+ }
+ else
+ {
+ for (a = code->ext.alloc_list; a; a = a->next)
+ resolve_deallocate_expr (a->expr);
+ }
+}
/************ SELECT CASE resolution subroutines ************/
@@ -6090,7 +6165,6 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
int omp_workshare_save;
int forall_save;
code_stack frame;
- gfc_alloc *a;
try t;
frame.prev = cs_base;
@@ -6275,25 +6349,14 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
break;
case EXEC_ALLOCATE:
- if (t == SUCCESS && code->expr != NULL
- && code->expr->ts.type != BT_INTEGER)
- gfc_error ("STAT tag in ALLOCATE statement at %L must be "
- "of type INTEGER", &code->expr->where);
-
- for (a = code->ext.alloc_list; a; a = a->next)
- resolve_allocate_expr (a->expr, code);
+ if (t == SUCCESS)
+ resolve_allocate_deallocate (code, "ALLOCATE");
break;
case EXEC_DEALLOCATE:
- if (t == SUCCESS && code->expr != NULL
- && code->expr->ts.type != BT_INTEGER)
- gfc_error
- ("STAT tag in DEALLOCATE statement at %L must be of type "
- "INTEGER", &code->expr->where);
-
- for (a = code->ext.alloc_list; a; a = a->next)
- resolve_deallocate_expr (a->expr);
+ if (t == SUCCESS)
+ resolve_allocate_deallocate (code, "DEALLOCATE");
break;