This problem was caused by the compiler attempting to use 0 as an lvalue and to assign 0 to it. Understandably, this upset the gimplifer quite a bit :-) The fix is to use the ss_info string length for deferred length character components, where the hidden string length component has been used. The use of a constant as an lvalue is prevented by checking that the expression string length is a variable.
Regtests on FC33/x86_64 - OK for all three branches? Paul Fortran: Fix for class defined operators [PR99125]. 2021-02-23 Paul Thomas <pa...@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.
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index c6725659093..e85d63c3539 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -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 diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index e61492485b8..9d178360fc3 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -2471,7 +2471,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);
! { 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 <gs...@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