diff options
Diffstat (limited to 'gcc-4.6/gcc/fortran/resolve.c')
-rw-r--r-- | gcc-4.6/gcc/fortran/resolve.c | 152 |
1 files changed, 93 insertions, 59 deletions
diff --git a/gcc-4.6/gcc/fortran/resolve.c b/gcc-4.6/gcc/fortran/resolve.c index 0b7a753..84753b2 100644 --- a/gcc-4.6/gcc/fortran/resolve.c +++ b/gcc-4.6/gcc/fortran/resolve.c @@ -950,6 +950,9 @@ resolve_contained_functions (gfc_namespace *ns) } +static gfc_try resolve_fl_derived0 (gfc_symbol *sym); + + /* Resolve all of the elements of a structure constructor and make sure that the types are correct. The 'init' flag indicates that the given constructor is an initializer. */ @@ -965,7 +968,7 @@ resolve_structure_cons (gfc_expr *expr, int init) t = SUCCESS; if (expr->ts.type == BT_DERIVED) - resolve_symbol (expr->ts.u.derived); + resolve_fl_derived0 (expr->ts.u.derived); cons = gfc_constructor_first (expr->value.constructor); /* A constructor may have references if it is the result of substituting a @@ -3129,10 +3132,10 @@ resolve_function (gfc_expr *expr) "procedure within a PURE procedure", name, &expr->where); t = FAILURE; } - } - if (!pure_function (expr, &name) && name && gfc_implicit_pure (NULL)) - gfc_current_ns->proc_name->attr.implicit_pure = 0; + if (gfc_implicit_pure (NULL)) + gfc_current_ns->proc_name->attr.implicit_pure = 0; + } /* Functions without the RECURSIVE attribution are not allowed to * call themselves. */ @@ -3192,6 +3195,9 @@ pure_subroutine (gfc_code *c, gfc_symbol *sym) else if (gfc_pure (NULL)) gfc_error ("Subroutine call to '%s' at %L is not PURE", sym->name, &c->loc); + + if (gfc_implicit_pure (NULL)) + gfc_current_ns->proc_name->attr.implicit_pure = 0; } @@ -4552,10 +4558,11 @@ resolve_array_ref (gfc_array_ref *ar) /* Fill in the upper bound, which may be lower than the specified one for something like a(2:10:5), which is identical to a(2:7:5). Only relevant for strides not equal - to one. */ + to one. Don't try a division by zero. */ if (ar->dimen_type[i] == DIMEN_RANGE && ar->stride[i] != NULL && ar->stride[i]->expr_type == EXPR_CONSTANT - && mpz_cmp_si (ar->stride[i]->value.integer, 1L) != 0) + && mpz_cmp_si (ar->stride[i]->value.integer, 1L) != 0 + && mpz_cmp_si (ar->stride[i]->value.integer, 0L) != 0) { mpz_t size, end; @@ -5180,13 +5187,7 @@ check_host_association (gfc_expr *e) && sym->attr.contained) { /* Clear the shape, since it might not be valid. */ - if (e->shape != NULL) - { - for (n = 0; n < e->rank; n++) - mpz_clear (e->shape[n]); - - gfc_free (e->shape); - } + gfc_free_shape (&e->shape, e->rank); /* Give the expression the right symtree! */ gfc_find_sym_tree (e->symtree->name, NULL, 1, &st); @@ -6530,10 +6531,13 @@ gfc_expr_to_initialize (gfc_expr *e) for (i = 0; i < ref->u.ar.dimen; i++) ref->u.ar.start[i] = ref->u.ar.end[i] = ref->u.ar.stride[i] = NULL; - result->rank = ref->u.ar.dimen; break; } + gfc_free_shape (&result->shape, result->rank); + + /* Recalculate rank, shape, etc. */ + gfc_resolve_expr (result); return result; } @@ -6831,7 +6835,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) gfc_find_derived_vtab (ts.u.derived); } - if (pointer || (dimension == 0 && codimension == 0)) + if (dimension == 0 && codimension == 0) goto success; /* Make sure the last reference node is an array specifiction. */ @@ -8321,11 +8325,8 @@ ignore: result = SUCCESS; over: - for (i--; i >= 0; i--) - { - mpz_clear (shape[i]); - mpz_clear (shape2[i]); - } + gfc_clear_shape (shape, i); + gfc_clear_shape (shape2, i); return result; } @@ -9689,7 +9690,7 @@ build_default_init_expr (gfc_symbol *sym) int i; /* These symbols should never have a default initialization. */ - if ((sym->attr.dimension && !gfc_is_compile_time_shape (sym->as)) + if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy || sym->attr.pointer @@ -11242,9 +11243,14 @@ static gfc_try resolve_typebound_procedures (gfc_symbol* derived) { int op; + gfc_symbol* super_type; if (!derived->f2k_derived || !derived->f2k_derived->tb_sym_root) return SUCCESS; + + super_type = gfc_get_derived_super_type (derived); + if (super_type) + resolve_typebound_procedures (super_type); resolve_bindings_derived = derived; resolve_bindings_result = SUCCESS; @@ -11356,28 +11362,17 @@ ensure_not_abstract (gfc_symbol* sub, gfc_symbol* ancestor) } -/* Resolve the components of a derived type. */ +/* Resolve the components of a derived type. This does not have to wait until + resolution stage, but can be done as soon as the dt declaration has been + parsed. */ static gfc_try -resolve_fl_derived (gfc_symbol *sym) +resolve_fl_derived0 (gfc_symbol *sym) { gfc_symbol* super_type; gfc_component *c; super_type = gfc_get_derived_super_type (sym); - - if (sym->attr.is_class && sym->ts.u.derived == NULL) - { - /* Fix up incomplete CLASS symbols. */ - gfc_component *data = gfc_find_component (sym, "_data", true, true); - gfc_component *vptr = gfc_find_component (sym, "_vptr", true, true); - if (vptr->ts.u.derived == NULL) - { - gfc_symbol *vtab = gfc_find_derived_vtab (data->ts.u.derived); - gcc_assert (vtab); - vptr->ts.u.derived = vtab->ts.u.derived; - } - } /* F2008, C432. */ if (super_type && sym->attr.coarray_comp && !super_type->attr.coarray_comp) @@ -11389,7 +11384,7 @@ resolve_fl_derived (gfc_symbol *sym) } /* Ensure the extended type gets resolved before we do. */ - if (super_type && resolve_fl_derived (super_type) == FAILURE) + if (super_type && resolve_fl_derived0 (super_type) == FAILURE) return FAILURE; /* An ABSTRACT type must be extensible. */ @@ -11402,6 +11397,14 @@ resolve_fl_derived (gfc_symbol *sym) for (c = sym->components; c != NULL; c = c->next) { + /* See PRs 51550, 47545, 48654, 49050, 51075 - and 45170. */ + if (c->ts.type == BT_CHARACTER && c->ts.deferred) + { + gfc_error ("Deferred-length character component '%s' at %L is not " + "yet supported", c->name, &c->loc); + return FAILURE; + } + /* F2008, C442. */ if (c->attr.codimension /* FIXME: c->as check due to PR 43412. */ && (!c->attr.allocatable || (c->as && c->as->type != AS_DEFERRED))) @@ -11742,14 +11745,6 @@ resolve_fl_derived (gfc_symbol *sym) return FAILURE; } - /* Resolve the type-bound procedures. */ - if (resolve_typebound_procedures (sym) == FAILURE) - return FAILURE; - - /* Resolve the finalizer procedures. */ - if (gfc_resolve_finalizers (sym) == FAILURE) - return FAILURE; - /* If this is a non-ABSTRACT type extending an ABSTRACT one, ensure that all DEFERRED bindings are overridden. */ if (super_type && super_type->attr.abstract && !sym->attr.abstract @@ -11764,6 +11759,42 @@ resolve_fl_derived (gfc_symbol *sym) } +/* The following procedure does the full resolution of a derived type, + including resolution of all type-bound procedures (if present). In contrast + to 'resolve_fl_derived0' this can only be done after the module has been + parsed completely. */ + +static gfc_try +resolve_fl_derived (gfc_symbol *sym) +{ + if (sym->attr.is_class && sym->ts.u.derived == NULL) + { + /* Fix up incomplete CLASS symbols. */ + gfc_component *data = gfc_find_component (sym, "_data", true, true); + gfc_component *vptr = gfc_find_component (sym, "_vptr", true, true); + if (vptr->ts.u.derived == NULL) + { + gfc_symbol *vtab = gfc_find_derived_vtab (data->ts.u.derived); + gcc_assert (vtab); + vptr->ts.u.derived = vtab->ts.u.derived; + } + } + + if (resolve_fl_derived0 (sym) == FAILURE) + return FAILURE; + + /* Resolve the type-bound procedures. */ + if (resolve_typebound_procedures (sym) == FAILURE) + return FAILURE; + + /* Resolve the finalizer procedures. */ + if (gfc_resolve_finalizers (sym) == FAILURE) + return FAILURE; + + return SUCCESS; +} + + static gfc_try resolve_fl_namelist (gfc_symbol *sym) { @@ -12076,6 +12107,8 @@ resolve_symbol (gfc_symbol *sym) } } } + else if (mp_flag && sym->attr.flavor == FL_PROCEDURE && sym->attr.function) + gfc_resolve_array_spec (sym->result->as, false); /* Assumed size arrays and assumed shape arrays must be dummy arguments. Array-spec's of implied-shape should have been resolved to @@ -12903,24 +12936,25 @@ gfc_pure (gfc_symbol *sym) int gfc_implicit_pure (gfc_symbol *sym) { - symbol_attribute attr; + gfc_namespace *ns; if (sym == NULL) { - /* Check if the current namespace is implicit_pure. */ - sym = gfc_current_ns->proc_name; - if (sym == NULL) - return 0; - attr = sym->attr; - if (attr.flavor == FL_PROCEDURE - && attr.implicit_pure && !attr.pure) - return 1; - return 0; + /* Check if the current procedure is implicit_pure. Walk up + the procedure list until we find a procedure. */ + for (ns = gfc_current_ns; ns; ns = ns->parent) + { + sym = ns->proc_name; + if (sym == NULL) + return 0; + + if (sym->attr.flavor == FL_PROCEDURE) + break; + } } - - attr = sym->attr; - - return attr.flavor == FL_PROCEDURE && attr.implicit_pure && !attr.pure; + + return sym->attr.flavor == FL_PROCEDURE && sym->attr.implicit_pure + && !sym->attr.pure; } |