re PR fortran/77325 (ICE in gimplify_var_or_parm_decl, at gimplify.c:1933)
authorPaul Thomas <pault@gcc.gnu.org>
Fri, 21 Sep 2018 17:33:29 +0000 (17:33 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Fri, 21 Sep 2018 17:33:29 +0000 (17:33 +0000)
2018-09-21  Paul Thomas  <pault@gcc.gnu.org>

PR fortran/77325
* trans-array.c (gfc_alloc_allocatable_for_assignment): If the
rhs has a charlen expression, convert that and use it.
* trans-expr.c (gfc_trans_assignment_1): The rse.pre for the
assignment of deferred character array vars to a realocatable
lhs should not be added to the exterior block since vector
indices, for example, generate temporaries indexed within the
loop.

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

PR fortran/77325
* gfortran.dg/deferred_character_22.f90 : New test.

From-SVN: r264486

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

index 0d8797eaab0fe62bd229ff0e2dfa1603e0559d00..e6bf429494810861b8b9bbc30efe938bef1e7a30 100644 (file)
@@ -1,3 +1,14 @@
+2018-09-21  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/77325
+       * trans-array.c (gfc_alloc_allocatable_for_assignment): If the
+       rhs has a charlen expression, convert that and use it.
+       * trans-expr.c (gfc_trans_assignment_1): The rse.pre for the
+       assignment of deferred character array vars to a realocatable
+       lhs should not be added to the exterior block since vector
+       indices, for example, generate temporaries indexed within the
+       loop.
+
 2018-09-21  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/87359
index 95ea61550cf5adff4fccd1684cb07b60c0856b32..9e00eb0474faf4838d64b9d671df262aa3c12539 100644 (file)
@@ -9964,6 +9964,15 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
              tmp = concat_str_length (expr2);
              expr2->ts.u.cl->backend_decl = gfc_evaluate_now (tmp, &fblock);
            }
+         else if (!tmp && expr2->ts.u.cl->length)
+           {
+             gfc_se tmpse;
+             gfc_init_se (&tmpse, NULL);
+             gfc_conv_expr_type (&tmpse, expr2->ts.u.cl->length,
+                                 gfc_charlen_type_node);
+             tmp = tmpse.expr;
+             expr2->ts.u.cl->backend_decl = gfc_evaluate_now (tmp, &fblock);
+           }
          tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);
        }
 
index 1f94dcf11dd5f6f8f404cbbf872f0cf70671867d..1453828684bfb5885d3fda51c5cbd5935fdd3d23 100644 (file)
@@ -10275,17 +10275,21 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
   /* When assigning a character function result to a deferred-length variable,
      the function call must happen before the (re)allocation of the lhs -
      otherwise the character length of the result is not known.
-     NOTE: This relies on having the exact dependence of the length type
+     NOTE 1: This relies on having the exact dependence of the length type
      parameter available to the caller; gfortran saves it in the .mod files.
-     NOTE ALSO: The concatenation operation generates a temporary pointer,
+     NOTE 2: Vector array references generate an index temporary that must
+     not go outside the loop. Otherwise, variables should not generate
+     a pre block.
+     NOTE 3: The concatenation operation generates a temporary pointer,
      whose allocation must go to the innermost loop.
-     NOTE ALSO (2): Elemental functions may generate a temporary, too.  */
+     NOTE 4: Elemental functions may generate a temporary, too.  */
   if (flag_realloc_lhs
       && expr2->ts.type == BT_CHARACTER && expr1->ts.deferred
       && !(lss != gfc_ss_terminator
           && rss != gfc_ss_terminator
-          && ((expr2->expr_type == EXPR_FUNCTION
-               && expr2->value.function.esym != NULL
+          && ((expr2->expr_type == EXPR_VARIABLE && expr2->rank)
+              || (expr2->expr_type == EXPR_FUNCTION
+                  && expr2->value.function.esym != NULL
                   && expr2->value.function.esym->attr.elemental)
               || (expr2->expr_type == EXPR_FUNCTION
                   && expr2->value.function.isym != NULL
index 97b60da78ec915679b7934c04ac1286c8598caa6..ea6cefb5f35cb2185cc6a4571db104aa38a19cd5 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-21  Paul Thomas  <pault@gcc.gnu.org>
+
+       PR fortran/77325
+       * gfortran.dg/deferred_character_22.f90 : New test.
+
 2018-09-21  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/87359
diff --git a/gcc/testsuite/gfortran.dg/deferred_character_22.f90 b/gcc/testsuite/gfortran.dg/deferred_character_22.f90
new file mode 100644 (file)
index 0000000..5037886
--- /dev/null
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! Test the fix for PR77325, which casued an ICE in the gimplifier. The
+! segafults in 'contains_struct_check' were found while diagnosing the PR.
+!
+! Contributed by Gerhard Steinmetz  <gerhard.steinmetz.fortran@t-online.de>
+!
+program p
+   character(3), parameter :: a(3) = ['abc', 'def', 'ghi']
+   character(1), parameter :: c(3) = ['a', 'b', 'c']
+   character(:), allocatable :: z(:)
+   z = c([3,2])          ! Vector subscripts caused an iCE in the gimplifier.
+   if (any (z .ne. ['c', 'b'])) stop 1
+   z = c
+   if (any (z .ne. ['a', 'b', 'c'])) stop 2
+   z = c(2:1:-1)
+   if (any (z .ne. ['b', 'a'])) stop 3
+   z = c(3)
+   if (any (z .ne. ['c', 'c'])) stop 4
+   z = a([3,1,2])
+   if (any (z .ne. ['ghi', 'abc', 'def'])) stop 5
+   z = a(1:2)(2:3)       ! Substrings caused a segfault in 'contains_struct_check'.
+   if (any (z .ne. ['bc', 'ef'])) stop 6
+   z = a([2,3,1])(2:3)   ! ditto
+   if (any (z .ne. ['ef', 'hi', 'bc'])) stop 7
+   deallocate (z)
+end