aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog26
-rw-r--r--gcc/fortran/decl.c30
-rw-r--r--gcc/fortran/resolve.c22
-rw-r--r--gcc/fortran/trans-array.c11
4 files changed, 80 insertions, 9 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 48d4334..449f9b8 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,29 @@
+2007-03-15 Tobias Burnus <burnus@gcc.gnu.org>
+ Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/30922
+ * decl.c (gfc_match_import): If the parent of the current name-
+ space is null, try looking for an imported symbol in the parent
+ of the proc_name interface.
+ * resolve.c (resolve_fl_variable): Do not check for blocking of
+ host association by a same symbol, if the symbol is in an
+ interface body.
+
+2007-03-15 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/30879
+ * decl.c (match_data_constant): Before going on to try to match
+ a name, try to match a structure component.
+
+
+ PR fortran/30870
+ * resolve.c (resolve_actual_arglist): Do not reject a generic
+ actual argument if it has a same name specific interface.
+
+ PR fortran/31163
+ * trans-array.c (parse_interface): Do not nullify allocatable
+ components if the symbol has the saved attribute.
+
2007-03-14 Francois-Xavier Coudert <coudert@clipper.ens.fr>
* trans-array.c (gfc_trans_auto_array_allocation): Replace
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 173ad45..09ded01 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -301,6 +301,7 @@ match_data_constant (gfc_expr **result)
gfc_symbol *sym;
gfc_expr *expr;
match m;
+ locus old_loc;
m = gfc_match_literal_constant (&expr, 1);
if (m == MATCH_YES)
@@ -316,6 +317,23 @@ match_data_constant (gfc_expr **result)
if (m != MATCH_NO)
return m;
+ old_loc = gfc_current_locus;
+
+ /* Should this be a structure component, try to match it
+ before matching a name. */
+ m = gfc_match_rvalue (result);
+ if (m == MATCH_ERROR)
+ return m;
+
+ if (m == MATCH_YES && (*result)->expr_type == EXPR_STRUCTURE)
+ {
+ if (gfc_simplify_expr (*result, 0) == FAILURE)
+ m = MATCH_ERROR;
+ return m;
+ }
+
+ gfc_current_locus = old_loc;
+
m = gfc_match_name (name);
if (m != MATCH_YES)
return m;
@@ -2041,7 +2059,17 @@ gfc_match_import (void)
switch (m)
{
case MATCH_YES:
- if (gfc_find_symbol (name, gfc_current_ns->parent, 1, &sym))
+ if (gfc_current_ns->parent != NULL
+ && gfc_find_symbol (name, gfc_current_ns->parent,
+ 1, &sym))
+ {
+ gfc_error ("Type name '%s' at %C is ambiguous", name);
+ return MATCH_ERROR;
+ }
+ else if (gfc_current_ns->proc_name->ns->parent != NULL
+ && gfc_find_symbol (name,
+ gfc_current_ns->proc_name->ns->parent,
+ 1, &sym))
{
gfc_error ("Type name '%s' at %C is ambiguous", name);
return MATCH_ERROR;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 987d73b..db55c0c 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -922,11 +922,24 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype)
&e->where);
}
+ /* Check if a generic interface has a specific procedure
+ with the same name before emitting an error. */
if (sym->attr.generic)
{
- gfc_error ("GENERIC non-INTRINSIC procedure '%s' is not "
- "allowed as an actual argument at %L", sym->name,
- &e->where);
+ gfc_interface *p;
+ for (p = sym->generic; p; p = p->next)
+ if (strcmp (sym->name, p->sym->name) == 0)
+ {
+ e->symtree = gfc_find_symtree
+ (p->sym->ns->sym_root, sym->name);
+ sym = p->sym;
+ break;
+ }
+
+ if (p == NULL || e->symtree == NULL)
+ gfc_error ("GENERIC non-INTRINSIC procedure '%s' is not "
+ "allowed as an actual argument at %L", sym->name,
+ &e->where);
}
/* If the symbol is the function that names the current (or
@@ -5663,7 +5676,8 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag)
/* Check to see if a derived type is blocked from being host associated
by the presence of another class I symbol in the same namespace.
14.6.1.3 of the standard and the discussion on comp.lang.fortran. */
- if (sym->ts.type == BT_DERIVED && sym->ns != sym->ts.derived->ns)
+ if (sym->ts.type == BT_DERIVED && sym->ns != sym->ts.derived->ns
+ && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY)
{
gfc_symbol *s;
gfc_find_symbol (sym->ts.derived->name, sym->ns, 0, &s);
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 5d41331..00e54c8 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -5216,9 +5216,12 @@ gfc_trans_deferred_array (gfc_symbol * sym, tree body)
if (sym_has_alloc_comp && !(sym->attr.pointer || sym->attr.allocatable))
{
- rank = sym->as ? sym->as->rank : 0;
- tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
- gfc_add_expr_to_block (&fnblock, tmp);
+ if (!sym->attr.save)
+ {
+ rank = sym->as ? sym->as->rank : 0;
+ tmp = gfc_nullify_alloc_comp (sym->ts.derived, descriptor, rank);
+ gfc_add_expr_to_block (&fnblock, tmp);
+ }
}
else if (!GFC_DESCRIPTOR_TYPE_P (type))
{
@@ -5239,7 +5242,7 @@ gfc_trans_deferred_array (gfc_symbol * sym, tree body)
/* Allocatable arrays need to be freed when they go out of scope.
The allocatable components of pointers must not be touched. */
if (sym_has_alloc_comp && !(sym->attr.function || sym->attr.result)
- && !sym->attr.pointer)
+ && !sym->attr.pointer && !sym->attr.save)
{
int rank;
rank = sym->as ? sym->as->rank : 0;