No functional changes in this patch.

gcc/fortran/ChangeLog
        * trans-openmp.cc (gfc_trans_omp_array_section): Add comments and
        use a more descriptive variable name.
---
 gcc/fortran/trans-openmp.cc | 58 ++++++++++++++++++++++++++++++-------
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 11873d3b6fe..fd4b19f6626 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -3352,7 +3352,24 @@ gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr 
*expr)
 static vec<tree, va_heap, vl_embed> *doacross_steps;
 
 
-/* Translate an array section or array element.  */
+/* Map an array section or array element.
+   BLOCK will hold any output statements generated; if there are iterators,
+     it's a block for the current iterator group.
+   OP is the construct containing the map clause.
+   N is the entry that appears in the clause namelist.  It may contain iterator
+     variables.
+   DECL is the base object associated with the namelist entry.  It can be an
+     array descriptor, a bare array, or pointer to an array.
+   ELEMENT is true for an array element, false for an array section.
+   OPENMP is true for OpenMP, false for OpenACC.
+   PTR_KIND is the map operation.
+   NODE is an input operand representing the map clause.
+   NODE2, NODE3, and NODE4 are output operands that will hold new map clauses
+     generated by this function.  Not all of them are always needed.  NODE2
+     is for an array descriptor object, NODE3 is for its data array, NODE4
+     is for a pointer mapping.
+   ITERATOR is a list of active iterator descriptors, chained through
+     TREE_CHAIN.  */
 
 static void
 gfc_trans_omp_array_section (stmtblock_t *block, gfc_exec_op op,
@@ -3362,7 +3379,10 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
                             tree iterator)
 {
   gfc_se se;
-  tree ptr, ptr2;
+  /* PTR is the array expression from n->expr.  If iterators are this
+     involved expression can involve iterator variables.  BASE points to the
+     base array object obtained from DECL.  */
+  tree ptr, base;
   tree elemsz = NULL_TREE;
 
   gfc_init_se (&se, NULL);
@@ -3429,11 +3449,13 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
       && OMP_CLAUSE_MAP_KIND (node) != GOMP_MAP_DELETE)
 
     {
+      /* NODE4 is a newly-generated map clause for the pointer.  */
       node4 = build_omp_clause (input_location,
                                OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
       OMP_CLAUSE_DECL (node4) = decl;
       OMP_CLAUSE_SIZE (node4) = size_int (0);
+      /* Make DECL be the descriptor rather than the pointer to it.  */
       decl = build_fold_indirect_ref (decl);
     }
   else if (ptr_kind == GOMP_MAP_ALWAYS_POINTER
@@ -3457,7 +3479,8 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
     {
       tree type = TREE_TYPE (decl);
-      ptr2 = gfc_conv_descriptor_data_get (decl);
+      base = gfc_conv_descriptor_data_get (decl);
+      /* NODE2 is a newly-generated map clause for the array descriptor DECL.  
*/
       node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
       OMP_CLAUSE_DECL (node2) = decl;
       OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
@@ -3474,6 +3497,7 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
        }
       else
        OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
+      /* NODE3 is a newly-generated map clause for the array data.  */
       node3 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (node3, ptr_kind);
       OMP_CLAUSE_DECL (node3) = gfc_conv_descriptor_data_get (decl);
@@ -3485,14 +3509,14 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
       if (ptr_kind == GOMP_MAP_ATTACH_DETACH && !openmp)
        STRIP_NOPS (OMP_CLAUSE_DECL (node3));
     }
-  else
+  else  /* DECL is bare array or pointer to an array.  */
     {
       if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
        {
          tree offset;
-         ptr2 = build_fold_addr_expr (decl);
+         base = build_fold_addr_expr (decl);
          offset = fold_build2 (MINUS_EXPR, ptrdiff_type_node, ptr,
-                               fold_convert (ptrdiff_type_node, ptr2));
+                               fold_convert (ptrdiff_type_node, base));
          offset = build2 (TRUNC_DIV_EXPR, ptrdiff_type_node,
                           offset, fold_convert (ptrdiff_type_node, elemsz));
          offset = build4_loc (input_location, ARRAY_REF,
@@ -3503,26 +3527,38 @@ gfc_trans_omp_array_section (stmtblock_t *block, 
gfc_exec_op op,
          if (ptr_kind == GOMP_MAP_ATTACH_DETACH && openmp)
            return;
        }
-      else
+      else  /* DECL is a pointer.  */
        {
          gcc_assert (POINTER_TYPE_P (TREE_TYPE (decl)));
-         ptr2 = decl;
+         base = decl;
        }
       node3 = build_omp_clause (input_location,
                                OMP_CLAUSE_MAP);
       OMP_CLAUSE_SET_MAP_KIND (node3, ptr_kind);
       OMP_CLAUSE_DECL (node3) = decl;
     }
-  ptr2 = fold_convert (ptrdiff_type_node, ptr2);
+
+  /* FIXME: This is a broken hack.  The ptr expression is based on the
+     namelist entry and can contain references to iterator variables, which
+     are not yet set to their initial values when ptr is used.  This
+     tries to replace instances of the iterator values with the initial values
+     in ptr explicitly.  It's broken because the expansion of ptr can also
+     add statements to the iterator block that also contain references to
+     the uninitialized variables, and substituting those similarly breaks
+     other things.  */
+  base = fold_convert (ptrdiff_type_node, base);
   for (tree it = iterator; it; it = TREE_CHAIN (it))
     {
       ptr = simplify_replace_tree (ptr, TREE_VEC_ELT (it, 0),
                                   TREE_VEC_ELT (it, 1));
-      ptr2 = simplify_replace_tree (ptr2, TREE_VEC_ELT (it, 0),
+      base = simplify_replace_tree (base, TREE_VEC_ELT (it, 0),
                                    TREE_VEC_ELT (it, 1));
     }
+
+  /* The OMP_CLAUSE_SIZE field for the array data map clause node3
+     contains the initial offset of ptr from base, not the size.  */
   OMP_CLAUSE_SIZE (node3) = fold_build2 (MINUS_EXPR, ptrdiff_type_node,
-                                        ptr, ptr2);
+                                        ptr, base);
 }
 
 static tree
-- 
2.39.5

Reply via email to