]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/54426 (FAIL: gfortran.dg/common_6.f90 -O (internal compiler error...
authorTobias Burnus <burnus@net-b.de>
Sun, 2 Sep 2012 06:40:27 +0000 (08:40 +0200)
committerTobias Burnus <burnus@gcc.gnu.org>
Sun, 2 Sep 2012 06:40:27 +0000 (08:40 +0200)
2012-09-02  Tobias Burnus  <burnus@net-b.de>

        PR fortran/54426
        * symbol.c (find_common_symtree): New function.
        (gfc_undo_symbols): Use it; free common_head if needed.

From-SVN: r190853

gcc/fortran/ChangeLog
gcc/fortran/symbol.c

index 582eb26f2c0c1c65ac7c972bc1a4f25e1d362b11..ea3bb324db27c282ce8679529b1d11583d83fc17 100644 (file)
@@ -1,3 +1,9 @@
+2012-09-02  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/54426
+       * symbol.c (find_common_symtree): New function.
+       (gfc_undo_symbols): Use it; free common_head if needed.
+
 2012-08-28  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/54389
index 5e97c4086d103b7a29b8d4754a81450e6bc937ea..8d3b56c9569557332b4b92b66b9ca0c1df87696a 100644 (file)
@@ -2867,6 +2867,30 @@ gfc_get_ha_symbol (const char *name, gfc_symbol **result)
   return i;
 }
 
+
+/* Search for the symtree belonging to a gfc_common_head; we cannot use
+   head->name as the common_root symtree's name might be mangled.  */
+
+static gfc_symtree *
+find_common_symtree (gfc_symtree *st, gfc_common_head *head)
+{
+
+  gfc_symtree *result;
+
+  if (st == NULL)
+    return NULL;
+
+  if (st->n.common == head)
+    return st;
+
+  result = find_common_symtree (st->left, head);
+  if (!result)  
+    result = find_common_symtree (st->right, head);
+
+  return result;
+}
+
+
 /* Undoes all the changes made to symbols in the current statement.
    This subroutine is made simpler due to the fact that attributes are
    never removed once added.  */
@@ -2890,6 +2914,17 @@ gfc_undo_symbols (void)
                 needs to be removed to stop the resolver looking
                 for a (possibly) dead symbol.  */
 
+             if (p->common_block->head == p && !p->common_next)
+               {
+                 gfc_symtree st, *st0;
+                 st0 = find_common_symtree (p->ns->common_root,
+                                            p->common_block);
+
+                 st.name = st0->name;
+                 gfc_delete_bbt (&p->ns->common_root, &st, compare_symtree);
+                 free (st0);
+               }
+
              if (p->common_block->head == p)
                p->common_block->head = p->common_next;
              else