Committed to trunk as rev. 268726. after adding a comment that a check for negative substring length is already present. The updated version is attached.
Thanks for the review. Will not backport unless requested. Harald On 02/08/19 21:36, Harald Anlauf wrote: > The attached patch attempts a substring length simplification > so that more complex expressions are handled in initialization > expressions. Thanks to Thomas König for the suggestion. > > Regtested on x86_64-pc-linux-gnu. > > (The PR still has other wrong-code issue to be addressed separately.) > > OK for trunk? And for backports to 8/7? > > Thanks, > Harald > > > 2019-02-08 Harald Anlauf <anl...@gmx.de> > > PR fortran/89077 > * resolve.c (gfc_resolve_substring_charlen): Check substring > length for constantness prior to general calculation of length. > > 2019-02-08 Harald Anlauf <anl...@gmx.de> > > PR fortran/89077 > * gfortran.dg/substr_simplify.f90: New test. > -- Harald Anlauf Dieburger Str. 17 60386 Frankfurt Tel.: (069) 4014 8318
Index: gcc/fortran/resolve.c =================================================================== --- gcc/fortran/resolve.c (revision 268725) +++ gcc/fortran/resolve.c (working copy) @@ -4965,6 +4965,7 @@ gfc_ref *char_ref; gfc_expr *start, *end; gfc_typespec *ts = NULL; + mpz_t diff; for (char_ref = e->ref; char_ref; char_ref = char_ref->next) { @@ -5016,12 +5017,26 @@ return; } - /* Length = (end - start + 1). */ - e->ts.u.cl->length = gfc_subtract (end, start); - e->ts.u.cl->length = gfc_add (e->ts.u.cl->length, - gfc_get_int_expr (gfc_charlen_int_kind, - NULL, 1)); + /* Length = (end - start + 1). + Check first whether it has a constant length. */ + if (gfc_dep_difference (end, start, &diff)) + { + gfc_expr *len = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind, + &e->where); + mpz_add_ui (len->value.integer, diff, 1); + mpz_clear (diff); + e->ts.u.cl->length = len; + /* The check for length < 0 is handled below */ + } + else + { + e->ts.u.cl->length = gfc_subtract (end, start); + e->ts.u.cl->length = gfc_add (e->ts.u.cl->length, + gfc_get_int_expr (gfc_charlen_int_kind, + NULL, 1)); + } + /* F2008, 6.4.1: Both the starting point and the ending point shall be within the range 1, 2, ..., n unless the starting point exceeds the ending point, in which case the substring has length zero. */