diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
commit | a926878ddbd5a98b272c22171ce58663fc04c3e0 (patch) | |
tree | 86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/fortran/resolve.c | |
parent | 542730f087133690b47e036dfd43eb0db8a650ce (diff) | |
parent | 07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff) | |
download | gcc-devel/autopar_devel.zip gcc-devel/autopar_devel.tar.gz gcc-devel/autopar_devel.tar.bz2 |
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 130 |
1 files changed, 90 insertions, 40 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index fd3b025..6caddcf 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1753,9 +1753,11 @@ gfc_resolve_intrinsic (gfc_symbol *sym, locus *loc) gfc_intrinsic_sym* isym = NULL; const char* symstd; - if (sym->formal) + if (sym->resolve_symbol_called >= 2) return true; + sym->resolve_symbol_called = 2; + /* Already resolved. */ if (sym->from_intmod && sym->ts.type != BT_UNKNOWN) return true; @@ -2275,12 +2277,28 @@ resolve_elemental_actual (gfc_expr *expr, gfc_code *c) && (set_by_optional || arg->expr->rank != rank) && !(isym && isym->id == GFC_ISYM_CONVERSION)) { - gfc_warning (OPT_Wpedantic, - "%qs at %L is an array and OPTIONAL; IF IT IS " - "MISSING, it cannot be the actual argument of an " - "ELEMENTAL procedure unless there is a non-optional " - "argument with the same rank (12.4.1.5)", - arg->expr->symtree->n.sym->name, &arg->expr->where); + bool t = false; + gfc_actual_arglist *a; + + /* Scan the argument list for a non-optional argument with the + same rank as arg. */ + for (a = arg0; a; a = a->next) + if (a != arg + && a->expr->rank == arg->expr->rank + && !a->expr->symtree->n.sym->attr.optional) + { + t = true; + break; + } + + if (!t) + gfc_warning (OPT_Wpedantic, + "%qs at %L is an array and OPTIONAL; If it is not " + "present, then it cannot be the actual argument of " + "an ELEMENTAL procedure unless there is a non-optional" + " argument with the same rank " + "(Fortran 2018, 15.5.2.12)", + arg->expr->symtree->n.sym->name, &arg->expr->where); } } @@ -2297,7 +2315,7 @@ resolve_elemental_actual (gfc_expr *expr, gfc_code *c) /* Elemental procedure's array actual arguments must conform. */ if (e != NULL) { - if (!gfc_check_conformance (arg->expr, e, "elemental procedure")) + if (!gfc_check_conformance (arg->expr, e, _("elemental procedure"))) return false; } else @@ -2616,6 +2634,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, int sub) gfc_error ("Interface mismatch in global procedure %qs at %L: %s", sym->name, &sym->declared_at, reason); + sym->error = 1; gfc_errors_to_warnings (false); goto done; } @@ -4172,9 +4191,9 @@ resolve_operator (gfc_expr *e) /* If op1 is BOZ, then op2 is not!. Try to convert to type of op2. */ if (op1->ts.type == BT_BOZ) { - if (gfc_invalid_boz ("BOZ literal constant near %L cannot appear as " - "an operand of a relational operator", - &op1->where)) + if (gfc_invalid_boz (G_("BOZ literal constant near %L cannot appear " + "as an operand of a relational operator"), + &op1->where)) return false; if (op2->ts.type == BT_INTEGER && !gfc_boz2int (op1, op2->ts.kind)) @@ -4187,8 +4206,8 @@ resolve_operator (gfc_expr *e) /* If op2 is BOZ, then op1 is not!. Try to convert to type of op2. */ if (op2->ts.type == BT_BOZ) { - if (gfc_invalid_boz ("BOZ literal constant near %L cannot appear as " - "an operand of a relational operator", + if (gfc_invalid_boz (G_("BOZ literal constant near %L cannot appear" + " as an operand of a relational operator"), &op2->where)) return false; @@ -4226,9 +4245,9 @@ resolve_operator (gfc_expr *e) const char *msg; if (op == INTRINSIC_EQ || op == INTRINSIC_EQ_OS) - msg = "Equality comparison for %s at %L"; + msg = G_("Equality comparison for %s at %L"); else - msg = "Inequality comparison for %s at %L"; + msg = G_("Inequality comparison for %s at %L"); gfc_warning (OPT_Wcompare_reals, msg, gfc_typename (op1), &op1->where); @@ -5138,9 +5157,6 @@ gfc_resolve_substring_charlen (gfc_expr *e) return; } - e->ts.type = BT_CHARACTER; - e->ts.kind = gfc_default_character_kind; - if (!e->ts.u.cl) e->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL); @@ -5555,6 +5571,7 @@ resolve_variable (gfc_expr *e) } /* TS 29113, C535b. */ else if (((sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->as && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK) || (sym->ts.type != BT_CLASS && sym->as @@ -5602,6 +5619,7 @@ resolve_variable (gfc_expr *e) /* TS 29113, C535b. */ if (((sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->as && CLASS_DATA (sym)->as->type == AS_ASSUMED_RANK) || (sym->ts.type != BT_CLASS && sym->as @@ -5975,6 +5993,16 @@ check_host_association (gfc_expr *e) if (ref->type == REF_ARRAY && ref->next == NULL) break; + if ((ref == NULL || ref->type != REF_ARRAY) + && sym->attr.proc == PROC_INTERNAL) + { + gfc_error ("%qs at %L is host associated at %L into " + "a contained procedure with an internal " + "procedure of the same name", sym->name, + &old_sym->declared_at, &e->where); + return false; + } + gcc_assert (ref->type == REF_ARRAY); /* Grab the start expressions from the array ref and @@ -8996,7 +9024,9 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) if (as->corank != 0) sym->attr.codimension = 1; } - else if (sym->ts.type == BT_CLASS && (!CLASS_DATA (sym)->as || sym->assoc->rankguessed)) + else if (sym->ts.type == BT_CLASS + && CLASS_DATA (sym) + && (!CLASS_DATA (sym)->as || sym->assoc->rankguessed)) { if (!CLASS_DATA (sym)->as) CLASS_DATA (sym)->as = gfc_get_array_spec (); @@ -9013,7 +9043,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) { /* target's rank is 0, but the type of the sym is still array valued, which has to be corrected. */ - if (sym->ts.type == BT_CLASS + if (sym->ts.type == BT_CLASS && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->as) { gfc_array_spec *as; @@ -9046,7 +9076,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target) as = NULL; sym->ts = *ts; sym->ts.type = BT_CLASS; - attr = CLASS_DATA (sym)->attr; + attr = CLASS_DATA (sym) ? CLASS_DATA (sym)->attr : sym->attr; attr.class_ok = 0; attr.associate_var = 1; attr.dimension = attr.codimension = 0; @@ -9225,7 +9255,8 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns) { if (code->expr1->symtree->n.sym->attr.untyped) code->expr1->symtree->n.sym->ts = code->expr2->ts; - selector_type = CLASS_DATA (code->expr2)->ts.u.derived; + selector_type = CLASS_DATA (code->expr2) + ? CLASS_DATA (code->expr2)->ts.u.derived : code->expr2->ts.u.derived; } if (code->expr2->rank && CLASS_DATA (code->expr1)->as) @@ -9636,7 +9667,7 @@ resolve_select_rank (gfc_code *code, gfc_namespace *old_ns) gfc_namespace *ns; gfc_code *body, *new_st, *tail; gfc_case *c; - char tname[GFC_MAX_SYMBOL_LEN]; + char tname[GFC_MAX_SYMBOL_LEN + 7]; char name[2 * GFC_MAX_SYMBOL_LEN]; gfc_symtree *st; gfc_expr *selector_expr = NULL; @@ -11799,10 +11830,18 @@ start: case EXEC_GOTO: if (code->expr1 != NULL) { - if (code->expr1->ts.type != BT_INTEGER) - gfc_error ("ASSIGNED GOTO statement at %L requires an " - "INTEGER variable", &code->expr1->where); - else if (code->expr1->symtree->n.sym->attr.assign != 1) + if (code->expr1->expr_type != EXPR_VARIABLE + || code->expr1->ts.type != BT_INTEGER + || (code->expr1->ref + && code->expr1->ref->type == REF_ARRAY) + || code->expr1->symtree == NULL + || (code->expr1->symtree->n.sym + && (code->expr1->symtree->n.sym->attr.flavor + == FL_PARAMETER))) + gfc_error ("ASSIGNED GOTO statement at %L requires a " + "scalar INTEGER variable", &code->expr1->where); + else if (code->expr1->symtree->n.sym + && code->expr1->symtree->n.sym->attr.assign != 1) gfc_error ("Variable %qs has not been assigned a target " "label at %L", code->expr1->symtree->n.sym->name, &code->expr1->where); @@ -11875,6 +11914,7 @@ start: || code->expr1->symtree->n.sym->ts.type != BT_INTEGER || code->expr1->symtree->n.sym->ts.kind != gfc_default_integer_kind + || code->expr1->symtree->n.sym->attr.flavor == FL_PARAMETER || code->expr1->symtree->n.sym->as != NULL)) gfc_error ("ASSIGN statement at %L requires a scalar " "default INTEGER variable", &code->expr1->where); @@ -12356,7 +12396,7 @@ resolve_charlen (gfc_charlen *cl) } /* cl->length has been resolved. It should have an integer type. */ - if (cl->length->ts.type != BT_INTEGER) + if (cl->length->ts.type != BT_INTEGER || cl->length->rank != 0) { gfc_error ("Scalar INTEGER expression expected at %L", &cl->length->where); @@ -12590,7 +12630,8 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag) { gfc_array_spec *as; - if (sym->ts.type == BT_CLASS && sym->attr.class_ok) + if (sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym)) as = CLASS_DATA (sym)->as; else as = sym->as; @@ -12600,7 +12641,8 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag) { bool pointer, allocatable, dimension; - if (sym->ts.type == BT_CLASS && sym->attr.class_ok) + if (sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym)) { pointer = CLASS_DATA (sym)->attr.class_pointer; allocatable = CLASS_DATA (sym)->attr.allocatable; @@ -12651,6 +12693,7 @@ resolve_fl_var_and_proc (gfc_symbol *sym, int mp_flag) { /* F03:C502. */ if (sym->attr.class_ok + && sym->ts.u.derived && !sym->attr.select_type_temporary && !UNLIMITED_POLY (sym) && !gfc_type_is_extensible (CLASS_DATA (sym)->ts.u.derived)) @@ -12689,7 +12732,8 @@ resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag) 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->ns != sym->ts.u.derived->ns + if (sym->ts.u.derived + && sym->ns != sym->ts.u.derived->ns && !sym->ts.u.derived->attr.use_assoc && sym->ns->proc_name->attr.if_source != IFSRC_IFBODY) { @@ -12893,8 +12937,7 @@ resolve_fl_variable (gfc_symbol *sym, int mp_flag) else if (sym->attr.external) gfc_error ("External %qs at %L cannot have an initializer", sym->name, &sym->declared_at); - else if (sym->attr.dummy - && !(sym->ts.type == BT_DERIVED && sym->attr.intent == INTENT_OUT)) + else if (sym->attr.dummy) gfc_error ("Dummy %qs at %L cannot have an initializer", sym->name, &sym->declared_at); else if (sym->attr.intrinsic) @@ -12997,6 +13040,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) { if (arg->sym && arg->sym->ts.type == BT_DERIVED + && arg->sym->ts.u.derived && !arg->sym->ts.u.derived->attr.use_assoc && !gfc_check_symbol_access (arg->sym->ts.u.derived) && !gfc_notify_std (GFC_STD_F2003, "%qs is of a PRIVATE type " @@ -13123,8 +13167,10 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) { if (sym->attr.proc_pointer) { + const char* name = (sym->attr.result ? sym->ns->proc_name->name + : sym->name); gfc_error ("Procedure pointer %qs at %L shall not be elemental", - sym->name, &sym->declared_at); + name, &sym->declared_at); return false; } if (sym->attr.dummy) @@ -13211,7 +13257,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) if (sym->attr.subroutine && sym->attr.result) { gfc_error ("PROCEDURE attribute conflicts with RESULT attribute " - "in %qs at %L", sym->name, &sym->declared_at); + "in %qs at %L", sym->ns->proc_name->name, &sym->declared_at); return false; } if (sym->attr.external && sym->attr.function && !sym->attr.module_procedure @@ -13909,7 +13955,7 @@ resolve_typebound_procedure (gfc_symtree* stree) { /* If proc has not been resolved at this point, proc->name may actually be a USE associated entity. See PR fortran/89647. */ - if (!proc->resolved + if (!proc->resolve_symbol_called && proc->attr.function == 0 && proc->attr.subroutine == 0) { gfc_symbol *tmp; @@ -15154,9 +15200,9 @@ resolve_symbol (gfc_symbol *sym) gfc_array_spec *as; bool saved_specification_expr; - if (sym->resolved) + if (sym->resolve_symbol_called >= 1) return; - sym->resolved = 1; + sym->resolve_symbol_called = 1; /* No symbol will ever have union type; only components can be unions. Union type declaration symbols have type BT_UNKNOWN but flavor FL_UNION @@ -15168,6 +15214,7 @@ resolve_symbol (gfc_symbol *sym) if (flag_coarray == GFC_FCOARRAY_LIB && sym->ts.type == BT_CLASS && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->attr.codimension + && CLASS_DATA (sym)->ts.u.derived && (CLASS_DATA (sym)->ts.u.derived->attr.alloc_comp || CLASS_DATA (sym)->ts.u.derived->attr.pointer_comp)) { @@ -15316,7 +15363,7 @@ resolve_symbol (gfc_symbol *sym) specification_expr = saved_specification_expr; } - if (sym->ts.type == BT_CLASS && sym->attr.class_ok) + if (sym->ts.type == BT_CLASS && sym->attr.class_ok && sym->ts.u.derived) { as = CLASS_DATA (sym)->as; class_attr = CLASS_DATA (sym)->attr; @@ -15717,6 +15764,7 @@ resolve_symbol (gfc_symbol *sym) /* F2008, C525. */ if ((((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp) || (sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->attr.coarray_comp)) || class_attr.codimension) && (sym->attr.result || sym->result == sym)) @@ -15738,6 +15786,7 @@ resolve_symbol (gfc_symbol *sym) /* F2008, C525. */ if (((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp) || (sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->attr.coarray_comp)) && (class_attr.codimension || class_attr.pointer || class_attr.dimension || class_attr.allocatable)) @@ -15781,6 +15830,7 @@ resolve_symbol (gfc_symbol *sym) /* F2008, C541. */ if ((((sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.coarray_comp) || (sym->ts.type == BT_CLASS && sym->attr.class_ok + && sym->ts.u.derived && CLASS_DATA (sym) && CLASS_DATA (sym)->attr.coarray_comp)) || (class_attr.codimension && class_attr.allocatable)) && sym->attr.dummy && sym->attr.intent == INTENT_OUT) @@ -15899,7 +15949,7 @@ resolve_symbol (gfc_symbol *sym) if (formal) { sym->formal_ns = formal->sym->ns; - if (sym->ns != formal->sym->ns) + if (sym->formal_ns && sym->ns != formal->sym->ns) sym->formal_ns->refs++; } } |