Hell world,

the attached patch is fairly self-explanatory, it fixes an out-of-memory
condition.

Regression-tested. OK for trunk?

Regards

        Thomas

2018-03-24  Thomas Koenig  <tkoe...@gcc.gnu.org>

        PR fortran/70068
        * expr.c (find_substring_ref): Change types of start, end
        and length variables to gfc_charlen_t. Set length to zero
        for empty substring.

2018-03-24  Thomas Koenig  <tkoe...@gcc.gnu.org>

        PR fortran/70068
        * gfortran.dg/substr_7.f90: New test.
Index: expr.c
===================================================================
--- expr.c	(revision 258501)
+++ expr.c	(working copy)
@@ -1662,9 +1662,9 @@ cleanup:
 static bool
 find_substring_ref (gfc_expr *p, gfc_expr **newp)
 {
-  int end;
-  int start;
-  int length;
+  gfc_charlen_t end;
+  gfc_charlen_t start;
+  gfc_charlen_t length;
   gfc_char_t *chr;
 
   if (p->ref->u.ss.start->expr_type != EXPR_CONSTANT
@@ -1674,9 +1674,12 @@ find_substring_ref (gfc_expr *p, gfc_expr **newp)
   *newp = gfc_copy_expr (p);
   free ((*newp)->value.character.string);
 
-  end = (int) mpz_get_ui (p->ref->u.ss.end->value.integer);
-  start = (int) mpz_get_ui (p->ref->u.ss.start->value.integer);
-  length = end - start + 1;
+  end = (gfc_charlen_t) mpz_get_ui (p->ref->u.ss.end->value.integer);
+  start = (gfc_charlen_t) mpz_get_ui (p->ref->u.ss.start->value.integer);
+  if (end >= start)
+    length = end - start + 1;
+  else
+    length = 0;
 
   chr = (*newp)->value.character.string = gfc_get_wide_string (length + 1);
   (*newp)->value.character.length = length;
! { dg-do  run }
! PR 70068 - used to allocate too much memory
! Original test cases by Gerhard Steinmetz
program p
   integer :: i
   character(3), parameter :: x(3) = ['abc', 'ijk', 'xyz']
   character(3) :: y(2)
   character(99), parameter :: x2(2) = ' '
   character(99), parameter :: y2=x(2)(99:1)
   y = [(x(i)(i:1), i=2,3)]
   if (any(y /= '')) call abort
   if (y2 /= '') call abort
end

Reply via email to