re PR fortran/88871 (ICE segmentation fault in f951)
authorThomas Koenig <tkoenig@gcc.gnu.org>
Sat, 19 Jan 2019 11:03:28 +0000 (11:03 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Sat, 19 Jan 2019 11:03:28 +0000 (11:03 +0000)
2019-01-17  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/88871
* resolve.c (resolve_ref): Fix logic for removal of
reference.

From-SVN: r268092

gcc/fortran/ChangeLog
gcc/fortran/resolve.c

index 675ce39e21b27fef4504a5d5ac7d478e39135247..21e4c884f7ca43764f63a91d55436cc0a82bbb37 100644 (file)
@@ -1,3 +1,9 @@
+2019-01-17  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/88871
+       * resolve.c (resolve_ref): Fix logic for removal of
+       reference.
+
 2019-01-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/88902
index b1c9292900323453ce898f809b88bbe947fde262..3f893f1f802f4a5d85e3dd1eb1de534f1ca843ae 100644 (file)
@@ -5046,6 +5046,7 @@ resolve_ref (gfc_expr *expr)
   int current_part_dimension, n_components, seen_part_dimension;
   gfc_ref *ref, **prev;
   bool equal_length;
+  bool breakout;
 
   for (ref = expr->ref; ref; ref = ref->next)
     if (ref->type == REF_ARRAY && ref->u.ar.as == NULL)
@@ -5054,12 +5055,12 @@ resolve_ref (gfc_expr *expr)
        break;
       }
 
-  
-  for (ref = expr->ref, prev = &expr->ref; ref; prev = &ref->next, ref = ref->next)
-    switch (ref->type)
+  breakout = false;
+  for (prev = &expr->ref; !breakout && *prev != NULL; prev = &(*prev)->next)
+    switch ((*prev)->type)
       {
       case REF_ARRAY:
-       if (!resolve_array_ref (&ref->u.ar))
+       if (!resolve_array_ref (&(*prev)->u.ar))
          return false;
        break;
 
@@ -5069,17 +5070,20 @@ resolve_ref (gfc_expr *expr)
 
       case REF_SUBSTRING:
        equal_length = false;
-       if (!resolve_substring (ref, &equal_length))
+       if (!resolve_substring (*prev, &equal_length))
          return false;
 
        if (expr->expr_type != EXPR_SUBSTRING && equal_length)
          {
            /* Remove the reference and move the charlen, if any.  */
+           ref = *prev;
            *prev = ref->next;
            ref->next = NULL;
            expr->ts.u.cl = ref->u.ss.length;
            ref->u.ss.length = NULL;
            gfc_free_ref_list (ref);
+           if (*prev == NULL)
+             breakout = true;
          }
        break;
       }