[fortran] PRs 70752 and 72709 - more deferred character length bugs

Message ID CAGkQGiKuKKOqk+mfrdRSu1+FR6QJcbiswr51p_-=7Xf5Vaa2nA@mail.gmail.com
State New
Headers show
Series
  • [fortran] PRs 70752 and 72709 - more deferred character length bugs
Related show

Commit Message

Paul Richard Thomas Sept. 25, 2018, 5:06 p.m.
This patch is a bit more complicated than some of the previous posts.
However, the ChangeLog explains the story pretty clearly.

Bootstraps and regtests on FC21/x86_64 - OK for trunk and 8-branch?

Again, better names for the testcases will be determined before committing.

Paul


2018-09-25  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/70752
    PR fortran/72709
    * trans-array.c (gfc_conv_scalarized_array_ref): If this is a
    deferred type and the info->descriptor is present, use the
    info->descriptor
    (gfc_conv_array_ref): Is the se expr is a descriptor type, pass
    it as 'decl' rather than the symbol backend_decl.
    (gfc_array_allocate): If the se string_length is a component
    reference, fix it and use it for the expression string length.
    Make use of component ref string lengths to set the descriptor
    'span'.
    (gfc_conv_expr_descriptor): For pointer assignment, do not set
    the span field if gfc_get_array_span returns zero.
    * trans.c (get_array_span): If the upper bound a character type
    is zero, use the descriptor span if available.


2018-09-25  Paul Thomas  <pault@gcc.gnu.org>

    PR fortran/70752
    * gfortran.dg/pr70752.f90 : New test.

    PR fortran/72709
    * gfortran.dg/pr72709.f90 : New test.

Comments

Janne Blomqvist Sept. 25, 2018, 6:41 p.m. | #1
On Tue, Sep 25, 2018 at 8:06 PM Paul Richard Thomas <
paul.richard.thomas@gmail.com> wrote:

> This patch is a bit more complicated than some of the previous posts.

> However, the ChangeLog explains the story pretty clearly.

>

> Bootstraps and regtests on FC21/x86_64 - OK for trunk and 8-branch?

>


+      if (expr->ts.kind != 1)
+        {
+          tmp = build_int_cst (gfc_array_index_type, expr->ts.kind);
+          tmp = fold_build2_loc (input_location, MULT_EXPR,
+                    gfc_array_index_type,
+                    se->string_length, tmp);
+        }

Is se->string_length guaranteed to be of type gfc_array_index_type_here? If
so, why? And if not, maybe a fold_convert is in order?

Otherwise, Ok.

-- 
Janne Blomqvist

Patch

diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 9e00eb0..1feba5e 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -3423,7 +3423,9 @@  gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
   /* A pointer array component can be detected from its field decl. Fix
      the descriptor, mark the resulting variable decl and pass it to
      gfc_build_array_ref.  */
-  if (is_pointer_array (info->descriptor))
+  if (is_pointer_array (info->descriptor)
+      || (expr && expr->ts.deferred && info->descriptor
+	  && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor))))
     {
       if (TREE_CODE (info->descriptor) == COMPONENT_REF)
 	decl = info->descriptor;
@@ -3676,7 +3678,12 @@  gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
   else if (expr->ts.deferred
 	   || (sym->ts.type == BT_CHARACTER
 	       && sym->attr.select_type_temporary))
-    decl = sym->backend_decl;
+    {
+      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr)))
+	decl = se->expr;
+      else
+	decl = sym->backend_decl;
+    }
   else if (sym->ts.type == BT_CLASS)
     decl = NULL_TREE;

@@ -5761,6 +5768,12 @@  gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,

   overflow = integer_zero_node;

+  if (expr->ts.type == BT_CHARACTER
+      && TREE_CODE (se->string_length) == COMPONENT_REF
+      && expr->ts.u.cl->backend_decl != se->string_length)
+    expr->ts.u.cl->backend_decl = gfc_evaluate_now (se->string_length,
+						    &se->pre);
+
   gfc_init_block (&set_descriptor_block);
   /* Take the corank only from the actual ref and not from the coref.  The
      later will mislead the generation of the array dimensions for allocatable/
@@ -5850,10 +5863,25 @@  gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
   /* Pointer arrays need the span field to be set.  */
   if (is_pointer_array (se->expr)
       || (expr->ts.type == BT_CLASS
-	  && CLASS_DATA (expr)->attr.class_pointer))
+	  && CLASS_DATA (expr)->attr.class_pointer)
+      || (expr->ts.type == BT_CHARACTER
+	  && TREE_CODE (se->string_length) == COMPONENT_REF))
     {
       if (expr3 && expr3_elem_size != NULL_TREE)
 	tmp = expr3_elem_size;
+      else if (se->string_length
+	       && TREE_CODE (se->string_length) == COMPONENT_REF)
+	{
+	  if (expr->ts.kind != 1)
+	    {
+	      tmp = build_int_cst (gfc_array_index_type, expr->ts.kind);
+	      tmp = fold_build2_loc (input_location, MULT_EXPR,
+				    gfc_array_index_type,
+				    se->string_length, tmp);
+	    }
+	  else
+	    tmp = se->string_length;
+	}
       else
 	tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (se->expr)));
       tmp = fold_convert (gfc_array_index_type, tmp);
@@ -7086,7 +7114,7 @@  gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)

 	      /* ....and set the span field.  */
 	      tmp = gfc_get_array_span (desc, expr);
-	      if (tmp != NULL_TREE)
+	      if (tmp != NULL_TREE && !integer_zerop (tmp))
 		gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp);
 	    }
 	  else if (se->want_pointer)
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 153bab6..ac583a0 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -327,6 +327,15 @@  get_array_span (tree type, tree decl)
 					TYPE_SIZE_UNIT (TREE_TYPE (type))),
 			  span);
     }
+  else if (type && TREE_CODE (type) == ARRAY_TYPE
+	   && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE
+	   && integer_zerop (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+    {
+      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
+	span = gfc_conv_descriptor_span_get (decl);
+      else
+	span = NULL_TREE;
+    }
   /* Likewise for class array or pointer array references.  */
   else if (TREE_CODE (decl) == FIELD_DECL
 	   || VAR_OR_FUNCTION_DECL_P (decl)