This is a another case of the gotcha's that come from trying to use ts.u.cl->backend_decl directly, where deferred length and even, in this case fixed length characters are concerned. The fix is to make use of the string length obtained from evaluation of the expression.
Regtested on FC31/x86_64 - OK for trunk? Paul 2020-02-29 Paul Thomas <pa...@gcc.gnu.org> PR fortran/92959 * trans-intrinsic.c (gfc_conv_associated): Eliminate 'nonzero_charlen' and move the chunk to evaluate zero character length until after the argument evaluation so that the string length can be used. 2020-02-29 Paul Thomas <pa...@gcc.gnu.org> PR fortran/92959 * gfortran.dg/associated_8.f90 : New test.
Index: gcc/fortran/trans-intrinsic.c =================================================================== *** gcc/fortran/trans-intrinsic.c (revision 279842) --- gcc/fortran/trans-intrinsic.c (working copy) *************** gfc_conv_associated (gfc_se *se, gfc_exp *** 8573,8579 **** gfc_se arg2se; tree tmp2; tree tmp; - tree nonzero_charlen; tree nonzero_arraylen; gfc_ss *ss; bool scalar; --- 8573,8578 ---- *************** gfc_conv_associated (gfc_se *se, gfc_exp *** 8629,8641 **** if (arg2->expr->ts.type == BT_CLASS) gfc_add_data_component (arg2->expr); - nonzero_charlen = NULL_TREE; - if (arg1->expr->ts.type == BT_CHARACTER) - nonzero_charlen = fold_build2_loc (input_location, NE_EXPR, - logical_type_node, - arg1->expr->ts.u.cl->backend_decl, - build_zero_cst - (TREE_TYPE (arg1->expr->ts.u.cl->backend_decl))); if (scalar) { /* A pointer to a scalar. */ --- 8628,8633 ---- *************** gfc_conv_associated (gfc_se *se, gfc_exp *** 8705,8714 **** /* If target is present zero character length pointers cannot be associated. */ ! if (nonzero_charlen != NULL_TREE) ! se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR, ! logical_type_node, ! se->expr, nonzero_charlen); } se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr); --- 8697,8711 ---- /* If target is present zero character length pointers cannot be associated. */ ! if (arg1->expr->ts.type == BT_CHARACTER) ! { ! tmp = arg1se.string_length; ! tmp = fold_build2_loc (input_location, NE_EXPR, ! logical_type_node, tmp, ! build_zero_cst (TREE_TYPE (tmp))); ! se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR, ! logical_type_node, se->expr, tmp); ! } } se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr); Index: gcc/testsuite/gfortran.dg/associated_8.f90 =================================================================== *** gcc/testsuite/gfortran.dg/associated_8.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/associated_8.f90 (working copy) *************** *** 0 **** --- 1,37 ---- + ! { dg-do run } + ! + ! Test the fix for PR92959, where compilation of ASSOCIATED segfaulted in 's1' and 's2'. + ! + ! Contributed by Gerhard Steinmetz <gs...@t-online.de> + ! + program p + character(:), pointer :: x, y => NULL() + character, pointer :: u, v => NULL () + character(4), target :: tgt = "abcd" + + ! Manifestly not associated + x => tgt + u => tgt(1:1) + call s1 (.false., 1) + call s2 (.false., 2) + ! Manifestly associated + y => x + v => u + call s1 (.true., 3) + call s2 (.true., 4) + ! Zero sized storage sequences must give a false. + y => tgt(1:0) + x => y + call s1 (.false., 5) + contains + subroutine s1 (state, err_no) + logical :: state + integer :: err_no + if (associated(x, y) .neqv. state) stop err_no + end + subroutine s2 (state, err_no) + logical :: state + integer :: err_no + if (associated(u, v) .neqv. state) stop err_no + end + end