Hi all,

the attached and committed (Rev. 209348) patch fixes two issues and prepares for pulling (getting) data from remote hosts by inserting an intrinsic function (inaccessible from the outside) when a coindexed expression is used. The code is a bit eager as it also adds it to the LHS of an assignment and in an allocate/deallocate statement - hence, I remove the intrinsic. I have a draft patch for trans-intrinsic.c, but I still need to clean it up.

The two issues, which the patch fixes were:

* When one has a coarray which is a component of a derived type, one also needs to include the variable when accessing it, not only the the tree decl of the component. And also polymorphic types have to be handled.

* For automatic arrays, the whole initialization got lost, leading to zero-sized arrays which shouldn't be zero sized. Let's hope that there are not too many similar bugs still lurking in the code.

Tobias
Index: ChangeLog.fortran-caf
===================================================================
--- ChangeLog.fortran-caf	(Revision 209347)
+++ ChangeLog.fortran-caf	(Arbeitskopie)
@@ -1,3 +1,15 @@
+2014-04-13  Tobias Burnus  <bur...@net-b.de>
+
+	* trans-decl.c (gfc_trans_deferred_vars): Fix bug in
+	condition.
+	* trans-expr.c (gfc_get_tree_for_caf_expr): Handle polymorphism
+	and coarray components of derived types.
+	* resolve.c (add_caf_get_intrinsic, remove_caf_get_intrinsic): New.
+	(resolve_variable, resolve_allocate_expr, resolve_code): Use it;
+	currently disabled.
+	(gfc_resolve_expr): Moved expression_rank call into
+	resolve_variable.
+
 2014-04-10  Tobias Burnus  <bur...@net-b.de>
 
 	* trans-intrinsic.c (caf_get_image_index, conv_caf_send):
Index: trans-decl.c
===================================================================
--- trans-decl.c	(Revision 209347)
+++ trans-decl.c	(Arbeitskopie)
@@ -3798,7 +3798,8 @@ gfc_trans_deferred_vars (gfc_symbol * proc_sym, gf
 					NULL_TREE);
 		  continue;
 		}
-	      else if (gfc_option.coarray != GFC_FCOARRAY_LIB)
+	      else if (gfc_option.coarray != GFC_FCOARRAY_LIB
+		       || !sym->attr.codimension)
 		{
 		  gfc_save_backend_locus (&loc);
 		  gfc_set_backend_locus (&sym->declared_at);
Index: resolve.c
===================================================================
--- resolve.c	(Revision 209347)
+++ resolve.c	(Arbeitskopie)
@@ -4728,6 +4728,40 @@ done:
 }
 
 
+static void
+add_caf_get_intrinsic (gfc_expr *e)
+{
+  gfc_expr *wrapper, *tmp_expr;
+  gfc_expr *async = gfc_get_logical_expr (gfc_default_logical_kind, NULL,
+					  false);
+  tmp_expr = XCNEW (gfc_expr);
+  *tmp_expr = *e;
+  wrapper = gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_CAF_GET,
+				      "caf_get", tmp_expr->where, 2,
+				      tmp_expr, async);
+  wrapper->ts = e->ts;
+  wrapper->rank = e->rank;
+  if (e->rank)
+    wrapper->shape = gfc_copy_shape (e->shape, e->rank);
+  *e = *wrapper;
+  free (wrapper);
+}
+
+
+static void
+remove_caf_get_intrinsic (gfc_expr *e)
+{
+  gcc_assert (e->expr_type == EXPR_FUNCTION && e->value.function.isym
+	      && e->value.function.isym->id == GFC_ISYM_CAF_GET);
+  gfc_expr *e2 = e->value.function.actual->expr;
+  e->value.function.actual->expr =NULL;
+  gfc_free_actual_arglist (e->value.function.actual);
+  gfc_free_shape (&e->shape, e->rank);
+  *e = *e2;
+  free (e2);
+}
+
+
 /* Resolve a variable expression.  */
 
 static bool
@@ -5007,6 +5041,12 @@ resolve_procedure:
 	}
     }
 
+  if (t)
+    expression_rank (e);
+
+  if (0 && t && gfc_option.coarray == GFC_FCOARRAY_LIB && gfc_is_coindexed (e))
+    add_caf_get_intrinsic(e);
+
   return t;
 }
 
@@ -6090,11 +6130,7 @@ gfc_resolve_expr (gfc_expr *e)
       if (check_host_association (e))
 	t = resolve_function (e);
       else
-	{
-	  t = resolve_variable (e);
-	  if (t)
-	    expression_rank (e);
-	}
+	t = resolve_variable (e);
 
       if (e->ts.type == BT_CHARACTER && e->ts.u.cl == NULL && e->ref
 	  && e->ref->type != REF_SUBSTRING)
@@ -6673,6 +6709,10 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code
   if (!gfc_resolve_expr (e))
     goto failure;
 
+  if (e->expr_type == EXPR_FUNCTION && e->value.function.isym
+      && e->value.function.isym->id == GFC_ISYM_CAF_GET)
+    remove_caf_get_intrinsic (e);
+
   /* Make sure the expression is allocatable or a pointer.  If it is
      pointer, the next-to-last reference must be a pointer.  */
 
@@ -9867,6 +9907,11 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
 	  if (!t)
 	    break;
 
+	  if (code->expr1->expr_type == EXPR_FUNCTION
+	      && code->expr1->value.function.isym
+	      && code->expr1->value.function.isym->id == GFC_ISYM_CAF_GET)
+	    remove_caf_get_intrinsic (code->expr1);
+
 	  if (!gfc_check_vardef_context (code->expr1, false, false, false, 
 					 _("assignment")))
 	    break;
Index: trans-expr.c
===================================================================
--- trans-expr.c	(Revision 209347)
+++ trans-expr.c	(Arbeitskopie)
@@ -1386,25 +1386,42 @@ gfc_get_expr_charlen (gfc_expr *e)
 tree
 gfc_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 (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)
-	  caf_decl = comp->backend_decl;
-       }
-
-   gcc_assert (caf_decl != NULL_TREE);
-   return caf_decl;
+	  {
+	    found = true;
+	    break;
+	  }
+      }
+  gcc_assert (found && caf_decl);
+  return caf_decl;
 }
 
 

Reply via email to