aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-stmt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-stmt.cc')
-rw-r--r--gcc/fortran/trans-stmt.cc133
1 files changed, 81 insertions, 52 deletions
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 41740ab..807fa8c 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -922,8 +922,8 @@ gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
if (gfc_expr_attr (code->expr1).dimension)
{
tree desc, tmp, extent, lbound, ubound;
- gfc_array_ref *ar, ar2;
- int i;
+ gfc_array_ref *ar, ar2;
+ int i, rank;
/* TODO: Extend this, once DT components are supported. */
ar = &code->expr1->ref->u.ar;
@@ -931,6 +931,8 @@ gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
memset (ar, '\0', sizeof (*ar));
ar->as = ar2.as;
ar->type = AR_FULL;
+ rank = code->expr1->rank;
+ code->expr1->rank = ar->as->rank;
gfc_init_se (&argse, NULL);
argse.descriptor_only = 1;
@@ -938,6 +940,7 @@ gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
gfc_add_block_to_block (&se.pre, &argse.pre);
desc = argse.expr;
*ar = ar2;
+ code->expr1->rank = rank;
extent = build_one_cst (gfc_array_index_type);
for (i = 0; i < ar->dimen; i++)
@@ -1740,6 +1743,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
tree charlen;
bool need_len_assign;
bool whole_array = true;
+ bool same_class;
gfc_ref *ref;
gfc_symbol *sym2;
@@ -1750,13 +1754,14 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
&& e->ts.type == BT_CLASS
&& (gfc_is_class_scalar_expr (e)
|| gfc_is_class_array_ref (e, NULL));
+ same_class = e->ts.type == BT_CLASS && sym->ts.type == BT_CLASS
+ && strcmp (sym->ts.u.derived->name, e->ts.u.derived->name) == 0;
unlimited = UNLIMITED_POLY (e);
for (ref = e->ref; ref; ref = ref->next)
- if (ref->type == REF_ARRAY
- && ref->u.ar.type == AR_FULL
- && ref->next)
+ if (ref->type == REF_ARRAY && ref->u.ar.type == AR_FULL
+ && ref->u.ar.dimen != 0 && ref->next)
{
whole_array = false;
break;
@@ -1905,7 +1910,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
gfc_add_init_cleanup (block, gfc_finish_block (&se.pre), tmp);
}
/* Now all the other kinds of associate variable. */
- else if (sym->attr.dimension && !class_target
+ else if ((sym->attr.dimension || sym->attr.codimension) && !class_target
&& (sym->as->type == AS_DEFERRED || sym->assoc->variable))
{
gfc_se se;
@@ -1931,6 +1936,9 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
}
+ if (sym->attr.codimension && !sym->attr.dimension)
+ se.want_coarray = 1;
+
gfc_conv_expr_descriptor (&se, e);
if (sym->ts.type == BT_CHARACTER
@@ -1994,7 +2002,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
/* Temporaries, arising from TYPE IS, just need the descriptor of class
arrays to be assigned directly. */
- else if (class_target && sym->attr.dimension
+ else if (class_target && (sym->attr.dimension || sym->attr.codimension)
&& (sym->ts.type == BT_DERIVED || unlimited))
{
gfc_se se;
@@ -2023,7 +2031,9 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
}
else
- gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
+ gfc_add_modify (&se.pre, sym->backend_decl,
+ build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (sym->backend_decl), se.expr));
if (unlimited)
{
@@ -2043,7 +2053,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
{
gfc_se se;
- gcc_assert (!sym->attr.dimension);
+ gcc_assert (!sym->attr.dimension && !sym->attr.codimension);
gfc_init_se (&se, NULL);
@@ -2123,6 +2133,14 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
e->symtree->name);
need_len_assign = false;
}
+ else if (whole_array && (same_class || unlimited)
+ && e->ts.type == BT_CLASS && CLASS_DATA (e)->attr.codimension)
+ {
+ gfc_expr *class_e = gfc_find_and_cut_at_last_class_ref (e);
+ gfc_conv_expr (&se, class_e);
+ gfc_free_expr (class_e);
+ need_len_assign = false;
+ }
else
{
/* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
@@ -2158,55 +2176,64 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
tree ctree = gfc_get_class_from_expr (se.expr);
tmp = TREE_TYPE (sym->backend_decl);
- /* F2018:19.5.1.6 "If a selector has the POINTER attribute,
- it shall be associated; the associate name is associated
- with the target of the pointer and does not have the
- POINTER attribute." */
- if (sym->ts.type == BT_CLASS
- && e->ts.type == BT_CLASS && e->rank == 0 && ctree
- && (!GFC_CLASS_TYPE_P (TREE_TYPE (se.expr))
- || CLASS_DATA (e)->attr.class_pointer))
+ if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS)
{
- tree stmp;
- tree dtmp;
- tree ctmp;
+ /* F2018:19.5.1.6 "If a selector has the POINTER attribute,
+ it shall be associated; the associate name is associated
+ with the target of the pointer and does not have the
+ POINTER attribute." */
+ if (e->rank == 0 && ctree
+ && (!GFC_CLASS_TYPE_P (TREE_TYPE (se.expr))
+ || CLASS_DATA (e)->attr.class_pointer))
+ {
+ tree stmp;
+ tree dtmp;
+ tree ctmp;
- ctmp = ctree;
- dtmp = TREE_TYPE (TREE_TYPE (sym->backend_decl));
- ctree = gfc_create_var (dtmp, "class");
+ ctmp = ctree;
+ dtmp = TREE_TYPE (TREE_TYPE (sym->backend_decl));
+ ctree = gfc_create_var (dtmp, "class");
- if (IS_INFERRED_TYPE (e)
- && !GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)))
- stmp = se.expr;
- else
- stmp = gfc_class_data_get (ctmp);
-
- /* Coarray scalar component expressions can emerge from
- the front end as array elements of the _data field. */
- if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (stmp)))
- stmp = gfc_conv_descriptor_data_get (stmp);
-
- if (!POINTER_TYPE_P (TREE_TYPE (stmp)))
- stmp = gfc_build_addr_expr (NULL, stmp);
-
- dtmp = gfc_class_data_get (ctree);
- stmp = fold_convert (TREE_TYPE (dtmp), stmp);
- gfc_add_modify (&se.pre, dtmp, stmp);
- stmp = gfc_class_vptr_get (ctmp);
- dtmp = gfc_class_vptr_get (ctree);
- stmp = fold_convert (TREE_TYPE (dtmp), stmp);
- gfc_add_modify (&se.pre, dtmp, stmp);
- if (UNLIMITED_POLY (sym))
- {
- stmp = gfc_class_len_get (ctmp);
- dtmp = gfc_class_len_get (ctree);
+ if (IS_INFERRED_TYPE (e)
+ && !GFC_CLASS_TYPE_P (TREE_TYPE (se.expr)))
+ stmp = se.expr;
+ else
+ stmp = gfc_class_data_get (ctmp);
+
+ /* Coarray scalar component expressions can emerge from
+ the front end as array elements of the _data field. */
+ if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (stmp)))
+ stmp = gfc_conv_descriptor_data_get (stmp);
+
+ if (!POINTER_TYPE_P (TREE_TYPE (stmp)))
+ stmp = gfc_build_addr_expr (NULL, stmp);
+
+ dtmp = gfc_class_data_get (ctree);
+ stmp = fold_convert (TREE_TYPE (dtmp), stmp);
+ gfc_add_modify (&se.pre, dtmp, stmp);
+ stmp = gfc_class_vptr_get (ctmp);
+ dtmp = gfc_class_vptr_get (ctree);
stmp = fold_convert (TREE_TYPE (dtmp), stmp);
gfc_add_modify (&se.pre, dtmp, stmp);
- need_len_assign = false;
+ if (UNLIMITED_POLY (sym))
+ {
+ stmp = gfc_class_len_get (ctmp);
+ dtmp = gfc_class_len_get (ctree);
+ stmp = fold_convert (TREE_TYPE (dtmp), stmp);
+ gfc_add_modify (&se.pre, dtmp, stmp);
+ need_len_assign = false;
+ }
+ se.expr = ctree;
+ }
+ else if (CLASS_DATA (sym)->attr.codimension)
+ {
+ gfc_conv_class_to_class (&se, e, sym->ts, false, false, false,
+ false);
+ tmp = se.expr;
}
- se.expr = ctree;
}
- tmp = gfc_build_addr_expr (tmp, se.expr);
+ if (!POINTER_TYPE_P (TREE_TYPE (se.expr)))
+ tmp = gfc_build_addr_expr (tmp, se.expr);
}
gfc_add_modify (&se.pre, sym->backend_decl, tmp);
@@ -6708,6 +6735,7 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
newsym->n.sym->backend_decl = expr3;
e3rhs = gfc_get_expr ();
e3rhs->rank = code->expr3->rank;
+ e3rhs->corank = code->expr3->corank;
e3rhs->symtree = newsym;
/* Mark the symbol referenced or gfc_trans_assignment will bug. */
newsym->n.sym->attr.referenced = 1;
@@ -6733,9 +6761,10 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
gfc_array_spec *arr;
arr = gfc_get_array_spec ();
arr->rank = e3rhs->rank;
+ arr->corank = e3rhs->corank;
arr->type = AS_DEFERRED;
/* Set the dimension and pointer attribute for arrays
- to be on the safe side. */
+ to be on the safe side. */
newsym->n.sym->attr.dimension = 1;
newsym->n.sym->attr.pointer = 1;
newsym->n.sym->as = arr;