aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/resolve.cc')
-rw-r--r--gcc/fortran/resolve.cc74
1 files changed, 34 insertions, 40 deletions
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index d09aef0..4a6e951 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -4807,34 +4807,6 @@ resolve_operator (gfc_expr *e)
return false;
}
}
-
- /* coranks have to be equal or one has to be zero to be combinable. */
- if (op1->corank == op2->corank || (op1->corank != 0 && op2->corank == 0))
- {
- e->corank = op1->corank;
- /* Only do this, when regular array has not set a shape yet. */
- if (e->shape == NULL)
- {
- if (op1->corank != 0)
- {
- e->shape = gfc_copy_shape (op1->shape, op1->corank);
- }
- }
- }
- else if (op1->corank == 0 && op2->corank != 0)
- {
- e->corank = op2->corank;
- /* Only do this, when regular array has not set a shape yet. */
- if (e->shape == NULL)
- e->shape = gfc_copy_shape (op2->shape, op2->corank);
- }
- else
- {
- gfc_error ("Inconsistent coranks for operator at %L and %L",
- &op1->where, &op2->where);
- return false;
- }
-
break;
case INTRINSIC_PARENTHESES:
@@ -6070,8 +6042,8 @@ gfc_op_rank_conformable (gfc_expr *op1, gfc_expr *op2)
gfc_expression_rank (op2);
return (op1->rank == 0 || op2->rank == 0 || op1->rank == op2->rank)
- && (op1->corank == 0 || op2->corank == 0
- || op1->corank == op2->corank);
+ && (op1->corank == 0 || op2->corank == 0 || op1->corank == op2->corank
+ || (!gfc_is_coindexed (op1) && !gfc_is_coindexed (op2)));
}
/* Resolve a variable expression. */
@@ -8740,8 +8712,25 @@ static bool
conformable_arrays (gfc_expr *e1, gfc_expr *e2)
{
gfc_ref *tail;
+ bool scalar;
+
for (tail = e2->ref; tail && tail->next; tail = tail->next);
+ /* If MOLD= is present and is not scalar, and the allocate-object has an
+ explicit-shape-spec, the ranks need not agree. This may be unintended,
+ so let's emit a warning if -Wsurprising is given. */
+ scalar = !tail || tail->type == REF_COMPONENT;
+ if (e1->mold && e1->rank > 0
+ && (scalar || (tail->type == REF_ARRAY && tail->u.ar.type != AR_FULL)))
+ {
+ if (scalar || (tail->u.ar.as && e1->rank != tail->u.ar.as->rank))
+ gfc_warning (OPT_Wsurprising, "Allocate-object at %L has rank %d "
+ "but MOLD= expression at %L has rank %d",
+ &e2->where, scalar ? 0 : tail->u.ar.as->rank,
+ &e1->where, e1->rank);
+ return true;
+ }
+
/* First compare rank. */
if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank))
|| (!tail && e1->rank != e2->rank))
@@ -10802,6 +10791,8 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
ref = gfc_copy_ref (ref);
}
+ gfc_expr *orig_expr1 = code->expr1;
+
/* Add EXEC_SELECT to switch on type. */
new_st = gfc_get_code (code->op);
new_st->expr1 = code->expr1;
@@ -10829,7 +10820,6 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
for (body = code->block; body; body = body->block)
{
gfc_symbol *vtab;
- gfc_expr *e;
c = body->ext.block.case_list;
/* Generate an index integer expression for address of the
@@ -10837,6 +10827,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
is stored in c->high and is used to resolve intrinsic cases. */
if (c->ts.type != BT_UNKNOWN)
{
+ gfc_expr *e;
if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
{
vtab = gfc_find_derived_vtab (c->ts.u.derived);
@@ -10869,11 +10860,13 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
when this case is actually true, so build a new ASSOCIATE
that does precisely this here (instead of using the
'global' one). */
-
+ const char * var_name = gfc_var_name_for_select_type_temp (orig_expr1);
if (c->ts.type == BT_CLASS)
- sprintf (name, "__tmp_class_%s", c->ts.u.derived->name);
+ snprintf (name, sizeof (name), "__tmp_class_%s_%s",
+ c->ts.u.derived->name, var_name);
else if (c->ts.type == BT_DERIVED)
- sprintf (name, "__tmp_type_%s", c->ts.u.derived->name);
+ snprintf (name, sizeof (name), "__tmp_type_%s_%s",
+ c->ts.u.derived->name, var_name);
else if (c->ts.type == BT_CHARACTER)
{
HOST_WIDE_INT charlen = 0;
@@ -10881,12 +10874,13 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
&& c->ts.u.cl->length->expr_type == EXPR_CONSTANT)
charlen = gfc_mpz_get_hwi (c->ts.u.cl->length->value.integer);
snprintf (name, sizeof (name),
- "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d",
- gfc_basic_typename (c->ts.type), charlen, c->ts.kind);
+ "__tmp_%s_" HOST_WIDE_INT_PRINT_DEC "_%d_%s",
+ gfc_basic_typename (c->ts.type), charlen, c->ts.kind,
+ var_name);
}
else
- sprintf (name, "__tmp_%s_%d", gfc_basic_typename (c->ts.type),
- c->ts.kind);
+ snprintf (name, sizeof (name), "__tmp_%s_%d_%s",
+ gfc_basic_typename (c->ts.type), c->ts.kind, var_name);
st = gfc_find_symtree (ns->sym_root, name);
gcc_assert (st->n.sym->assoc);
@@ -16819,8 +16813,8 @@ resolve_fl_derived0 (gfc_symbol *sym)
return false;
/* Now add the caf token field, where needed. */
- if (flag_coarray != GFC_FCOARRAY_NONE
- && !sym->attr.is_class && !sym->attr.vtype)
+ if (flag_coarray == GFC_FCOARRAY_LIB && !sym->attr.is_class
+ && !sym->attr.vtype)
{
for (c = sym->components; c; c = c->next)
if (!c->attr.dimension && !c->attr.codimension