]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fortran: Fix for class defined operators [PR99125].
authorPaul Thomas <pault@gcc.gnu.org>
Sat, 13 Mar 2021 11:39:57 +0000 (11:39 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Sat, 13 Mar 2021 11:39:57 +0000 (11:39 +0000)
2021-03-13  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/99125
* trans-array.c (gfc_conv_expr_descriptor): For deferred length
length components use the ss_info string length instead of
gfc_get_expr_charlen. Make sure that the deferred string length
is a variable before assigning to it. Otherwise use the expr.
* trans-expr.c (gfc_conv_string_length): Make sure that the
deferred string length is a variable before assigning to it.

gcc/testsuite/
PR fortran/99125
* gfortran.dg/alloc_deferred_comp_1.f90: New test.

gcc/fortran/trans-array.c
gcc/fortran/trans-expr.c
gcc/testsuite/gfortran.dg/alloc_deferred_comp_1.f90 [new file with mode: 0644]

index 478cddda0709f9d411eb95db186124d46621c8e4..be5eb89350f46bb0ab719c7609650f4508cbdf5f 100644 (file)
@@ -7670,15 +7670,21 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
       /* Set the string_length for a character array.  */
       if (expr->ts.type == BT_CHARACTER)
        {
-         se->string_length =  gfc_get_expr_charlen (expr);
+         if (deferred_array_component)
+           se->string_length = ss_info->string_length;
+         else
+           se->string_length =  gfc_get_expr_charlen (expr);
+
          if (VAR_P (se->string_length)
              && expr->ts.u.cl->backend_decl == se->string_length)
            tmp = ss_info->string_length;
          else
            tmp = se->string_length;
 
-         if (expr->ts.deferred)
+         if (expr->ts.deferred && VAR_P (expr->ts.u.cl->backend_decl))
            gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl, tmp);
+         else
+           expr->ts.u.cl->backend_decl = tmp;
        }
 
       /* If we have an array section, are assigning  or passing an array
index 85c16d7f4c3df97d333818e182235e909f92567e..f6ef5c023bf08670c54ee589b40edcfb96a7a3d5 100644 (file)
@@ -2485,7 +2485,7 @@ gfc_conv_string_length (gfc_charlen * cl, gfc_expr * expr, stmtblock_t * pblock)
                             se.expr, build_zero_cst (TREE_TYPE (se.expr)));
   gfc_add_block_to_block (pblock, &se.pre);
 
-  if (cl->backend_decl)
+  if (cl->backend_decl && VAR_P (cl->backend_decl))
     gfc_add_modify (pblock, cl->backend_decl, se.expr);
   else
     cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
diff --git a/gcc/testsuite/gfortran.dg/alloc_deferred_comp_1.f90 b/gcc/testsuite/gfortran.dg/alloc_deferred_comp_1.f90
new file mode 100644 (file)
index 0000000..0fc54d5
--- /dev/null
@@ -0,0 +1,18 @@
+! { dg-do run }
+!
+! Test the fix for PR99125, where the array reference in the print
+! statement caused an ICE because the gimplifier complained about '0'
+! being used as an lvalue.
+!
+! Contributed by Gerhard Steinmetz  <gscfq@t-online.de>
+!
+program p
+   type t
+      character(:), allocatable :: a(:)
+   end type
+   type(t) :: x
+   character(8) :: c(3) = ['12 45 78','23 56 89','34 67 90']
+   x%a = c
+   if (any (x%a(2:3) .ne. ['23 56 89','34 67 90'])) stop 1
+   if (any (x%a(2:3)(4:5) .ne. ['56','67'])) stop 2 ! Bizarrely this worked.
+end