This is yet another deferred character problem occurring at exactly the same place as 87239 and 84109. I found another bug while going along and so have fixed that too.
Bootstrapped and regtested on FC28/x86_64. I will apply all three to 8-branch in slightly more than one week's time. Paul 2018-09-21 Paul Thomas <pa...@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 <pa...@gcc.gnu.org> PR fortran/77325 * gfortran.dg/deferred_character_22.f90 : New test.
Index: gcc/fortran/trans-array.c =================================================================== *** gcc/fortran/trans-array.c (revision 264426) --- gcc/fortran/trans-array.c (working copy) *************** gfc_alloc_allocatable_for_assignment (gf *** 9964,9969 **** --- 9964,9978 ---- 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: gcc/fortran/trans-expr.c =================================================================== *** gcc/fortran/trans-expr.c (revision 264427) --- gcc/fortran/trans-expr.c (working copy) *************** gfc_trans_assignment_1 (gfc_expr * expr1 *** 10275,10291 **** /* 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 parameter available to the caller; gfortran saves it in the .mod files. ! NOTE ALSO: 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. */ 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->value.function.esym->attr.elemental) || (expr2->expr_type == EXPR_FUNCTION && expr2->value.function.isym != NULL --- 10275,10295 ---- /* 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 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 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 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_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: gcc/testsuite/gfortran.dg/deferred_character_22.f90 =================================================================== *** gcc/testsuite/gfortran.dg/deferred_character_22.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/deferred_character_22.f90 (working copy) *************** *** 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.fort...@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