aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/fortran/resolve.c
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-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.c130
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++;
}
}