aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorTobias Burnus <burnus@gcc.gnu.org>2014-04-30 20:39:15 +0200
committerTobias Burnus <burnus@gcc.gnu.org>2014-04-30 20:39:15 +0200
commit7f36b65d25e6882ac20d6baf80dd8f2c773aa7d7 (patch)
tree3c19344a498203b07329a3a73ad2382125dfb4a4 /gcc/fortran/trans-expr.c
parent332fddaddc37453024e7968841a6064fff7bfeb0 (diff)
downloadgcc-7f36b65d25e6882ac20d6baf80dd8f2c773aa7d7.zip
gcc-7f36b65d25e6882ac20d6baf80dd8f2c773aa7d7.tar.gz
gcc-7f36b65d25e6882ac20d6baf80dd8f2c773aa7d7.tar.bz2
trans-expr.c (get_tree_for_caf_expr): Fix handling of
2014-04-30 Tobias Burnus <burnus@net-b.de> * trans-expr.c (get_tree_for_caf_expr): Fix handling of * polymorphic and derived-type coarrays. 2014-04-30 Tobias Burnus <burnus@net-b.de> * gfortran.dg/coarray_poly_4.f90: New. * gfortran.dg/coarray_poly_5.f90: New. From-SVN: r209948
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index d6f820c..f0e5b7d 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -1387,25 +1387,42 @@ gfc_get_expr_charlen (gfc_expr *e)
static tree
get_tree_for_caf_expr (gfc_expr *expr)
{
- tree caf_decl = NULL_TREE;
- gfc_ref *ref;
+ tree caf_decl;
+ bool found;
+ gfc_ref *ref;
- gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
- if (expr->symtree->n.sym->attr.codimension)
- caf_decl = expr->symtree->n.sym->backend_decl;
+ gcc_assert (expr && expr->expr_type == EXPR_VARIABLE);
- for (ref = expr->ref; ref; ref = ref->next)
- if (ref->type == REF_COMPONENT)
- {
+ caf_decl = expr->symtree->n.sym->backend_decl;
+ gcc_assert (caf_decl);
+ if (expr->symtree->n.sym->ts.type == BT_CLASS)
+ caf_decl = gfc_class_data_get (caf_decl);
+ if (expr->symtree->n.sym->attr.codimension)
+ return caf_decl;
+
+ /* The following code assumes that the coarray is a component reachable via
+ only scalar components/variables; the Fortran standard guarantees this. */
+
+ for (ref = expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_COMPONENT)
+ {
gfc_component *comp = ref->u.c.component;
- if (comp->attr.pointer || comp->attr.allocatable)
- caf_decl = NULL_TREE;
- if (comp->attr.codimension)
- caf_decl = comp->backend_decl;
- }
- gcc_assert (caf_decl != NULL_TREE);
- return caf_decl;
+ if (POINTER_TYPE_P (TREE_TYPE (caf_decl)))
+ caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
+ caf_decl = fold_build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (comp->backend_decl), caf_decl,
+ comp->backend_decl, NULL_TREE);
+ if (comp->ts.type == BT_CLASS)
+ caf_decl = gfc_class_data_get (caf_decl);
+ if (comp->attr.codimension)
+ {
+ found = true;
+ break;
+ }
+ }
+ gcc_assert (found && caf_decl);
+ return caf_decl;
}