diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-02 16:08:13 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-10-02 16:08:13 +0000 |
commit | 49a71dabbf3f3619262fa291ae03e7e398a01418 (patch) | |
tree | fb872bd7055fc4dc775250a68d3c2c9ad1e5adbf /gcc/fortran/resolve.c | |
parent | f2046193319751a83837abb7ea740d233446937c (diff) | |
download | gcc-49a71dabbf3f3619262fa291ae03e7e398a01418.tar.gz |
2009-10-02 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 152404
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@152406 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 379 |
1 files changed, 309 insertions, 70 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 3eec50e5373..bb803b3475c 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -879,7 +879,10 @@ resolve_structure_cons (gfc_expr *expr) if (cons->expr->expr_type == EXPR_NULL && !(comp->attr.pointer || comp->attr.allocatable - || comp->attr.proc_pointer)) + || comp->attr.proc_pointer + || (comp->ts.type == BT_CLASS + && (comp->ts.u.derived->components->attr.pointer + || comp->ts.u.derived->components->attr.allocatable)))) { t = FAILURE; gfc_error ("The NULL in the derived type constructor at %L is " @@ -3931,7 +3934,10 @@ find_array_spec (gfc_expr *e) gfc_symbol *derived; gfc_ref *ref; - as = e->symtree->n.sym->as; + if (e->symtree->n.sym->ts.type == BT_CLASS) + as = e->symtree->n.sym->ts.u.derived->components->as; + else + as = e->symtree->n.sym->as; derived = NULL; for (ref = e->ref; ref; ref = ref->next) @@ -4844,8 +4850,9 @@ check_typebound_baseobject (gfc_expr* e) if (!base) return FAILURE; - gcc_assert (base->ts.type == BT_DERIVED); - if (base->ts.u.derived->attr.abstract) + gcc_assert (base->ts.type == BT_DERIVED || base->ts.type == BT_CLASS); + + if (base->ts.type == BT_DERIVED && base->ts.u.derived->attr.abstract) { gfc_error ("Base object for type-bound procedure call at %L is of" " ABSTRACT type '%s'", &e->where, base->ts.u.derived->name); @@ -5051,7 +5058,10 @@ static gfc_try resolve_ppc_call (gfc_code* c) { gfc_component *comp; - gcc_assert (gfc_is_proc_ptr_comp (c->expr1, &comp)); + bool b; + + b = gfc_is_proc_ptr_comp (c->expr1, &comp); + gcc_assert (b); c->resolved_sym = c->expr1->symtree->n.sym; c->expr1->expr_type = EXPR_VARIABLE; @@ -5083,7 +5093,10 @@ static gfc_try resolve_expr_ppc (gfc_expr* e) { gfc_component *comp; - gcc_assert (gfc_is_proc_ptr_comp (e, &comp)); + bool b; + + b = gfc_is_proc_ptr_comp (e, &comp); + gcc_assert (b); /* Convert to EXPR_FUNCTION. */ e->expr_type = EXPR_FUNCTION; @@ -5462,6 +5475,8 @@ resolve_deallocate_expr (gfc_expr *e) symbol_attribute attr; int allocatable, pointer, check_intent_in; gfc_ref *ref; + gfc_symbol *sym; + gfc_component *c; /* Check INTENT(IN), unless the object is a sub-component of a pointer. */ check_intent_in = 1; @@ -5472,8 +5487,18 @@ resolve_deallocate_expr (gfc_expr *e) if (e->expr_type != EXPR_VARIABLE) goto bad; - allocatable = e->symtree->n.sym->attr.allocatable; - pointer = e->symtree->n.sym->attr.pointer; + sym = e->symtree->n.sym; + + if (sym->ts.type == BT_CLASS) + { + allocatable = sym->ts.u.derived->components->attr.allocatable; + pointer = sym->ts.u.derived->components->attr.pointer; + } + else + { + allocatable = sym->attr.allocatable; + pointer = sym->attr.pointer; + } for (ref = e->ref; ref; ref = ref->next) { if (pointer) @@ -5487,9 +5512,17 @@ resolve_deallocate_expr (gfc_expr *e) break; case REF_COMPONENT: - allocatable = (ref->u.c.component->as != NULL - && ref->u.c.component->as->type == AS_DEFERRED); - pointer = ref->u.c.component->attr.pointer; + c = ref->u.c.component; + if (c->ts.type == BT_CLASS) + { + allocatable = c->ts.u.derived->components->attr.allocatable; + pointer = c->ts.u.derived->components->attr.pointer; + } + else + { + allocatable = c->attr.allocatable; + pointer = c->attr.pointer; + } break; case REF_SUBSTRING: @@ -5507,14 +5540,19 @@ resolve_deallocate_expr (gfc_expr *e) &e->where); } - if (check_intent_in - && e->symtree->n.sym->attr.intent == INTENT_IN) + if (check_intent_in && sym->attr.intent == INTENT_IN) { gfc_error ("Cannot deallocate INTENT(IN) variable '%s' at %L", - e->symtree->n.sym->name, &e->where); + sym->name, &e->where); return FAILURE; } + if (e->ts.type == BT_CLASS) + { + /* Only deallocate the DATA component. */ + gfc_add_component_ref (e, "$data"); + } + return SUCCESS; } @@ -5541,8 +5579,8 @@ gfc_find_sym_in_expr (gfc_symbol *sym, gfc_expr *e) derived types with default initializers, and derived types with allocatable components that need nullification.) */ -static gfc_expr * -expr_to_initialize (gfc_expr *e) +gfc_expr * +gfc_expr_to_initialize (gfc_expr *e) { gfc_expr *result; gfc_ref *ref; @@ -5579,9 +5617,9 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) gfc_ref *ref, *ref2; gfc_array_ref *ar; gfc_code *init_st; - gfc_expr *init_e; gfc_symbol *sym; gfc_alloc *a; + gfc_component *c; /* Check INTENT(IN), unless the object is a sub-component of a pointer. */ check_intent_in = 1; @@ -5593,6 +5631,8 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) pointer, the next-to-last reference must be a pointer. */ ref2 = NULL; + if (e->symtree) + sym = e->symtree->n.sym; if (e->expr_type != EXPR_VARIABLE) { @@ -5603,9 +5643,18 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) } else { - allocatable = e->symtree->n.sym->attr.allocatable; - pointer = e->symtree->n.sym->attr.pointer; - dimension = e->symtree->n.sym->attr.dimension; + if (sym->ts.type == BT_CLASS) + { + allocatable = sym->ts.u.derived->components->attr.allocatable; + pointer = sym->ts.u.derived->components->attr.pointer; + dimension = sym->ts.u.derived->components->attr.dimension; + } + else + { + allocatable = sym->attr.allocatable; + pointer = sym->attr.pointer; + dimension = sym->attr.dimension; + } for (ref = e->ref; ref; ref2 = ref, ref = ref->next) { @@ -5620,11 +5669,19 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) break; case REF_COMPONENT: - allocatable = (ref->u.c.component->as != NULL - && ref->u.c.component->as->type == AS_DEFERRED); - - pointer = ref->u.c.component->attr.pointer; - dimension = ref->u.c.component->attr.dimension; + c = ref->u.c.component; + if (c->ts.type == BT_CLASS) + { + allocatable = c->ts.u.derived->components->attr.allocatable; + pointer = c->ts.u.derived->components->attr.pointer; + dimension = c->ts.u.derived->components->attr.dimension; + } + else + { + allocatable = c->attr.allocatable; + pointer = c->attr.pointer; + dimension = c->attr.dimension; + } break; case REF_SUBSTRING: @@ -5642,24 +5699,46 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) return FAILURE; } - if (check_intent_in - && e->symtree->n.sym->attr.intent == INTENT_IN) + if (check_intent_in && sym->attr.intent == INTENT_IN) { gfc_error ("Cannot allocate INTENT(IN) variable '%s' at %L", - e->symtree->n.sym->name, &e->where); + sym->name, &e->where); return FAILURE; } - /* Add default initializer for those derived types that need them. */ - if (e->ts.type == BT_DERIVED && (init_e = gfc_default_initializer (&e->ts))) + if (e->ts.type == BT_CLASS) { + /* Initialize VINDEX for CLASS objects. */ init_st = gfc_get_code (); init_st->loc = code->loc; - init_st->op = EXEC_INIT_ASSIGN; - init_st->expr1 = expr_to_initialize (e); - init_st->expr2 = init_e; + init_st->expr1 = gfc_expr_to_initialize (e); + init_st->op = EXEC_ASSIGN; + gfc_add_component_ref (init_st->expr1, "$vindex"); + if (code->expr3 && code->expr3->ts.type == BT_CLASS) + { + /* vindex must be determined at run time. */ + init_st->expr2 = gfc_copy_expr (code->expr3); + gfc_add_component_ref (init_st->expr2, "$vindex"); + } + else + { + /* vindex is fixed at compile time. */ + int vindex; + if (code->expr3) + vindex = code->expr3->ts.u.derived->vindex; + else if (code->ext.alloc.ts.type == BT_DERIVED) + vindex = code->ext.alloc.ts.u.derived->vindex; + else if (e->ts.type == BT_CLASS) + vindex = e->ts.u.derived->components->ts.u.derived->vindex; + else + vindex = e->ts.u.derived->vindex; + init_st->expr2 = gfc_int_expr (vindex); + } + init_st->expr2->where = init_st->expr1->where = init_st->loc; init_st->next = code->next; code->next = init_st; + /* Only allocate the DATA component. */ + gfc_add_component_ref (e, "$data"); } if (pointer || dimension == 0) @@ -5706,7 +5785,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code) check_symbols: - for (a = code->ext.alloc_list; a; a = a->next) + for (a = code->ext.alloc.list; a; a = a->next) { sym = a->expr->symtree->n.sym; @@ -5758,7 +5837,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn) gfc_error ("Stat-variable at %L must be a scalar INTEGER " "variable", &stat->where); - for (p = code->ext.alloc_list; p; p = p->next) + for (p = code->ext.alloc.list; p; p = p->next) if (p->expr->symtree->n.sym->name == stat->symtree->n.sym->name) gfc_error ("Stat-variable at %L shall not be %sd within " "the same %s statement", &stat->where, fcn, fcn); @@ -5787,7 +5866,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn) gfc_error ("Errmsg-variable at %L must be a scalar CHARACTER " "variable", &errmsg->where); - for (p = code->ext.alloc_list; p; p = p->next) + for (p = code->ext.alloc.list; p; p = p->next) if (p->expr->symtree->n.sym->name == errmsg->symtree->n.sym->name) gfc_error ("Errmsg-variable at %L shall not be %sd within " "the same %s statement", &errmsg->where, fcn, fcn); @@ -5795,7 +5874,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn) /* Check that an allocate-object appears only once in the statement. FIXME: Checking derived types is disabled. */ - for (p = code->ext.alloc_list; p; p = p->next) + for (p = code->ext.alloc.list; p; p = p->next) { pe = p->expr; if ((pe->ref && pe->ref->type != REF_COMPONENT) @@ -5815,12 +5894,12 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn) if (strcmp (fcn, "ALLOCATE") == 0) { - for (a = code->ext.alloc_list; a; a = a->next) + 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) + for (a = code->ext.alloc.list; a; a = a->next) resolve_deallocate_expr (a->expr); } } @@ -6346,6 +6425,116 @@ resolve_select (gfc_code *code) } +/* Check if a derived type is extensible. */ + +bool +gfc_type_is_extensible (gfc_symbol *sym) +{ + return !(sym->attr.is_bind_c || sym->attr.sequence); +} + + +/* Resolve a SELECT TYPE statement. */ + +static void +resolve_select_type (gfc_code *code) +{ + gfc_symbol *selector_type; + gfc_code *body, *new_st; + gfc_case *c, *default_case; + gfc_symtree *st; + char name[GFC_MAX_SYMBOL_LEN]; + + selector_type = code->expr1->ts.u.derived->components->ts.u.derived; + + /* Assume there is no DEFAULT case. */ + default_case = NULL; + + /* Loop over TYPE IS / CLASS IS cases. */ + for (body = code->block; body; body = body->block) + { + c = body->ext.case_list; + + /* Check F03:C815. */ + if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS) + && !gfc_type_is_extensible (c->ts.u.derived)) + { + gfc_error ("Derived type '%s' at %L must be extensible", + c->ts.u.derived->name, &c->where); + continue; + } + + /* Check F03:C816. */ + if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS) + && !gfc_type_is_extension_of (selector_type, c->ts.u.derived)) + { + gfc_error ("Derived type '%s' at %L must be an extension of '%s'", + c->ts.u.derived->name, &c->where, selector_type->name); + continue; + } + + /* Intercept the DEFAULT case. */ + if (c->ts.type == BT_UNKNOWN) + { + /* Check F03:C818. */ + if (default_case != NULL) + gfc_error ("The DEFAULT CASE at %L cannot be followed " + "by a second DEFAULT CASE at %L", + &default_case->where, &c->where); + else + default_case = c; + continue; + } + } + + /* Transform to EXEC_SELECT. */ + code->op = EXEC_SELECT; + gfc_add_component_ref (code->expr1, "$vindex"); + + /* Loop over TYPE IS / CLASS IS cases. */ + for (body = code->block; body; body = body->block) + { + c = body->ext.case_list; + if (c->ts.type == BT_DERIVED) + c->low = c->high = gfc_int_expr (c->ts.u.derived->vindex); + else if (c->ts.type == BT_CLASS) + /* Currently IS CLASS blocks are simply ignored. + TODO: Implement IS CLASS. */ + c->unreachable = 1; + + if (c->ts.type != BT_DERIVED) + continue; + /* Assign temporary to selector. */ + sprintf (name, "tmp$%s", c->ts.u.derived->name); + st = gfc_find_symtree (code->expr1->symtree->n.sym->ns->sym_root, name); + new_st = gfc_get_code (); + new_st->op = EXEC_POINTER_ASSIGN; + new_st->expr1 = gfc_get_variable_expr (st); + new_st->expr2 = gfc_get_variable_expr (code->expr1->symtree); + gfc_add_component_ref (new_st->expr2, "$data"); + new_st->next = body->next; + body->next = new_st; + } + + /* Eliminate dead blocks. */ + for (body = code; body && body->block; body = body->block) + { + if (body->block->ext.case_list->unreachable) + { + /* Cut the unreachable block from the code chain. */ + gfc_code *cd = body->block; + body->block = cd->block; + /* Kill the dead block, but not the blocks below it. */ + cd->block = NULL; + gfc_free_statements (cd); + } + } + + resolve_select (code); + +} + + /* Resolve a transfer statement. This is making sure that: -- a derived type being transferred has only non-pointer components -- a derived type being transferred doesn't have private components, unless @@ -6911,6 +7100,7 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns) break; case EXEC_SELECT: + case EXEC_SELECT_TYPE: case EXEC_FORALL: case EXEC_DO: case EXEC_DO_WHILE: @@ -7102,6 +7292,44 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns) } +/* Check an assignment to a CLASS object (pointer or ordinary assignment). */ + +static void +resolve_class_assign (gfc_code *code) +{ + gfc_code *assign_code = gfc_get_code (); + + if (code->expr2->ts.type != BT_CLASS) + { + /* Insert an additional assignment which sets the vindex. */ + assign_code->next = code->next; + code->next = assign_code; + assign_code->op = EXEC_ASSIGN; + assign_code->expr1 = gfc_copy_expr (code->expr1); + gfc_add_component_ref (assign_code->expr1, "$vindex"); + if (code->expr2->ts.type == BT_DERIVED) + /* vindex is constant, determined at compile time. */ + assign_code->expr2 = gfc_int_expr (code->expr2->ts.u.derived->vindex); + else if (code->expr2->ts.type == BT_CLASS) + { + /* vindex must be determined at run time. */ + assign_code->expr2 = gfc_copy_expr (code->expr2); + gfc_add_component_ref (assign_code->expr2, "$vindex"); + } + else if (code->expr2->expr_type == EXPR_NULL) + assign_code->expr2 = gfc_int_expr (0); + else + gcc_unreachable (); + } + + /* Modify the actual pointer assignment. */ + if (code->expr2->ts.type == BT_CLASS) + code->op = EXEC_ASSIGN; + else + gfc_add_component_ref (code->expr1, "$data"); +} + + /* Given a block of code, recursively resolve everything pointed to by this code block. */ @@ -7224,6 +7452,9 @@ resolve_code (gfc_code *code, gfc_namespace *ns) if (t == FAILURE) break; + if (code->expr1->ts.type == BT_CLASS) + resolve_class_assign (code); + if (resolve_ordinary_assign (code, ns)) { if (code->op == EXEC_COMPCALL) @@ -7252,7 +7483,11 @@ resolve_code (gfc_code *code, gfc_namespace *ns) if (t == FAILURE) break; + if (code->expr1->ts.type == BT_CLASS) + resolve_class_assign (code); + gfc_check_pointer_assign (code->expr1, code->expr2); + break; case EXEC_ARITHMETIC_IF: @@ -7295,6 +7530,10 @@ resolve_code (gfc_code *code, gfc_namespace *ns) resolve_select (code); break; + case EXEC_SELECT_TYPE: + resolve_select_type (code); + break; + case EXEC_BLOCK: gfc_resolve (code->ext.ns); break; @@ -8023,8 +8262,8 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag) } else { - if (!mp_flag && !sym->attr.allocatable - && !sym->attr.pointer && !sym->attr.dummy) + if (!mp_flag && !sym->attr.allocatable && !sym->attr.pointer + && !sym->attr.dummy && sym->ts.type != BT_CLASS) { gfc_error ("Array '%s' at %L cannot have a deferred shape", sym->name, &sym->declared_at); @@ -8035,22 +8274,13 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag) } -/* Check if a derived type is extensible. */ - -static bool -type_is_extensible (gfc_symbol *sym) -{ - return !(sym->attr.is_bind_c || sym->attr.sequence); -} - - /* Additional checks for symbols with flavor variable and derived type. To be called from resolve_fl_variable. */ static gfc_try resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag) { - gcc_assert (sym->ts.type == BT_DERIVED); + gcc_assert (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS); /* Check to see if a derived type is blocked from being host associated by the presence of another class I symbol in the same @@ -8092,10 +8322,10 @@ resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag) return FAILURE; } - if (sym->ts.is_class) + if (sym->ts.type == BT_CLASS) { /* C502. */ - if (!type_is_extensible (sym->ts.u.derived)) + if (!gfc_type_is_extensible (sym->ts.u.derived->components->ts.u.derived)) { gfc_error ("Type '%s' of CLASS variable '%s' at %L is not extensible", sym->ts.u.derived->name, sym->name, &sym->declared_at); @@ -8103,7 +8333,9 @@ resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag) } /* C509. */ - if (!(sym->attr.dummy || sym->attr.allocatable || sym->attr.pointer)) + if (!(sym->attr.dummy || sym->attr.allocatable || sym->attr.pointer + || sym->ts.u.derived->components->attr.allocatable + || sym->ts.u.derived->components->attr.pointer)) { gfc_error ("CLASS variable '%s' at %L must be dummy, allocatable " "or pointer", sym->name, &sym->declared_at); @@ -8244,7 +8476,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag) } no_init_error: - if (sym->ts.type == BT_DERIVED) + if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS) return resolve_fl_variable_derived (sym, no_init_flag); return SUCCESS; @@ -8890,6 +9122,9 @@ check_generic_tbp_ambiguity (gfc_tbp_generic* t1, gfc_tbp_generic* t2, sym1 = t1->specific->u.specific->n.sym; sym2 = t2->specific->u.specific->n.sym; + if (sym1 == sym2) + return SUCCESS; + /* Both must be SUBROUTINEs or both must be FUNCTIONs. */ if (sym1->attr.subroutine != sym2->attr.subroutine || sym1->attr.function != sym2->attr.function) @@ -9283,21 +9518,22 @@ resolve_typebound_procedure (gfc_symtree* stree) /* Now check that the argument-type matches. */ gcc_assert (me_arg); - if (me_arg->ts.type != BT_DERIVED - || me_arg->ts.u.derived != resolve_bindings_derived) + if (me_arg->ts.type != BT_CLASS) { - gfc_error ("Argument '%s' of '%s' with PASS(%s) at %L must be of" - " the derived-type '%s'", me_arg->name, proc->name, - me_arg->name, &where, resolve_bindings_derived->name); + gfc_error ("Non-polymorphic passed-object dummy argument of '%s'" + " at %L", proc->name, &where); goto error; } - if (!me_arg->ts.is_class) + if (me_arg->ts.u.derived->components->ts.u.derived + != resolve_bindings_derived) { - gfc_error ("Non-polymorphic passed-object dummy argument of '%s'" - " at %L", proc->name, &where); + gfc_error ("Argument '%s' of '%s' with PASS(%s) at %L must be of" + " the derived-type '%s'", me_arg->name, proc->name, + me_arg->name, &where, resolve_bindings_derived->name); goto error; } + } /* If we are extending some type, check that we don't override a procedure @@ -9475,7 +9711,7 @@ resolve_fl_derived (gfc_symbol *sym) return FAILURE; /* An ABSTRACT type must be extensible. */ - if (sym->attr.abstract && !type_is_extensible (sym)) + if (sym->attr.abstract && !gfc_type_is_extensible (sym)) { gfc_error ("Non-extensible derived-type '%s' at %L must not be ABSTRACT", sym->name, &sym->declared_at); @@ -9611,8 +9847,10 @@ resolve_fl_derived (gfc_symbol *sym) /* Now check that the argument-type matches. */ gcc_assert (me_arg); - if (me_arg->ts.type != BT_DERIVED - || me_arg->ts.u.derived != sym) + if ((me_arg->ts.type != BT_DERIVED && me_arg->ts.type != BT_CLASS) + || (me_arg->ts.type == BT_DERIVED && me_arg->ts.u.derived != sym) + || (me_arg->ts.type == BT_CLASS + && me_arg->ts.u.derived->components->ts.u.derived != sym)) { gfc_error ("Argument '%s' of '%s' with PASS(%s) at %L must be of" " the derived type '%s'", me_arg->name, c->name, @@ -9649,9 +9887,9 @@ resolve_fl_derived (gfc_symbol *sym) return FAILURE; } - if (type_is_extensible (sym) && !me_arg->ts.is_class) + if (gfc_type_is_extensible (sym) && me_arg->ts.type != BT_CLASS) gfc_error ("Non-polymorphic passed-object dummy argument of '%s'" - " at %L", c->name, &c->loc); + " at %L", c->name, &c->loc); } @@ -9720,8 +9958,9 @@ resolve_fl_derived (gfc_symbol *sym) } /* C437. */ - if (c->ts.type == BT_DERIVED && c->ts.is_class - && !(c->attr.pointer || c->attr.allocatable)) + if (c->ts.type == BT_CLASS + && !(c->ts.u.derived->components->attr.pointer + || c->ts.u.derived->components->attr.allocatable)) { gfc_error ("Component '%s' with CLASS at %L must be allocatable " "or pointer", c->name, &c->loc); |