Hi all,

attached patch adds a call to sync_all after an ALLOCATE allocating a coarray.
This is to adhere to standard wanting:

..., execution of the segment (11.6.2) following the statement is delayed until
all other active images in the current team have executed the same statement the
same number of times in this team.

This, esp. the "statement", means that assigning the SOURCE= is to come before
the sync all, which means we have to do it explicitly after that assignment. Or
the other way around the sync all can be done in library caf_register().

Bootstraps and regtests ok on x86_64-linux/F23. Ok for trunk?

Regards,
        Andre
-- 
Andre Vehreschild * Email: vehre ad gmx dot de 
gcc/fortran/ChangeLog:

2016-12-02  Andre Vehreschild  <ve...@gcc.gnu.org>

        PR fortran/78505
        * trans-stmt.c (gfc_trans_allocate): Add sync all after the execution
        of the whole allocate-statement to adhere to the standard.

gcc/testsuite/ChangeLog:

2016-12-02  Andre Vehreschild  <ve...@gcc.gnu.org>

        PR fortran/78505
        * gfortran.dg/coarray_alloc_with_implicit_sync_1.f90: New test.


diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 514db28..2219bcc 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -5506,7 +5506,7 @@ gfc_trans_allocate (gfc_code * code)
   stmtblock_t block;
   stmtblock_t post;
   tree nelems;
-  bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
+  bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray ;
   gfc_symtree *newsym = NULL;
 
   if (!code->ext.alloc.list)
@@ -5516,6 +5516,7 @@ gfc_trans_allocate (gfc_code * code)
   expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
   label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
   e3_is = E3_UNSET;
+  is_coarray = false;
 
   gfc_init_block (&block);
   gfc_init_block (&post);
@@ -5555,8 +5556,9 @@ gfc_trans_allocate (gfc_code * code)
      expression.  */
   if (code->expr3)
     {
-      bool vtab_needed = false, temp_var_needed = false,
-	  is_coarray = gfc_is_coarray (code->expr3);
+      bool vtab_needed = false, temp_var_needed = false;
+
+      is_coarray = gfc_is_coarray (code->expr3);
 
       /* Figure whether we need the vtab from expr3.  */
       for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
@@ -6093,6 +6095,9 @@ gfc_trans_allocate (gfc_code * code)
 	      tree caf_decl, token;
 	      gfc_se caf_se;
 
+	      /* Set flag, to add synchronize after the allocate.  */
+	      is_coarray = true;
+
 	      gfc_init_se (&caf_se, NULL);
 
 	      caf_decl = gfc_get_tree_for_caf_expr (expr);
@@ -6114,6 +6119,11 @@ gfc_trans_allocate (gfc_code * code)
 	}
       else
 	{
+	  /* Allocating coarrays needs a sync after the allocate executed.
+	     Set the flag to add the sync after all objects are allocated.  */
+	  is_coarray = is_coarray || (gfc_caf_attr (expr).codimension
+				      && flag_coarray == GFC_FCOARRAY_LIB);
+
 	  if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
 	      && expr3_len != NULL_TREE)
 	    {
@@ -6357,6 +6367,15 @@ gfc_trans_allocate (gfc_code * code)
       gfc_add_modify (&block, se.expr, tmp);
     }
 
+  if (is_coarray && flag_coarray == GFC_FCOARRAY_LIB)
+    {
+      /* Add a sync all after the allocation has been executed.  */
+      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
+				 3, null_pointer_node, null_pointer_node,
+				 integer_zero_node);
+      gfc_add_expr_to_block (&post, tmp);
+    }
+
   gfc_add_block_to_block (&block, &se.post);
   gfc_add_block_to_block (&block, &post);
 
diff --git a/gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90 b/gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90
new file mode 100644
index 0000000..1dbbcb7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_alloc_with_implicit_sync_1.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original -fcoarray=lib" }
+! Check that allocating a coarray adds an implicit sync all.
+ 
+ implicit none
+ integer, allocatable :: f(:)[:]
+ allocate( f(20)[*], source = 1 )
+end
+
+! { dg-final { scan-tree-dump-times "_gfortran_caf_sync_all \\(" 1 "original" } }

Reply via email to