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.  */

Reply via email to