http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59746

Bud Davis <bdavis at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bdavis at gcc dot gnu.org

--- Comment #2 from Bud Davis <bdavis at gcc dot gnu.org> ---
it looks like what was happening was the variable that was previously defined,
NVE, was not getting deleted out of the common block by
restore_last_undo_checkpoint.  Then the next time it was called, the common
block list was messed up.

The code would only remove a variable from a common block if it was just
defined in the previous statement.  I changed it so it would remove a variable
from a common block if it was just defined, or if it previously existed and was
put in the common block in the last statement.

This patch works with the example given and has no regressions in the
testsuite.

Short on time, wanted to save this info so it is not lost.  If anyone wants to
finish this up (testcase, blah. blah...) please feel free to do so.

--bud davis



[bdavis@budlinux1 current]$ svn diff gcc
Index: gcc/gcc/fortran/symbol.c
===================================================================
--- gcc/gcc/fortran/symbol.c    (revision 208254)
+++ gcc/gcc/fortran/symbol.c    (working copy)
@@ -3069,9 +3069,10 @@

   FOR_EACH_VEC_ELT (latest_undo_chgset->syms, i, p)
     {
-      if (p->gfc_new)
+      if (p->gfc_new || (p->old_symbol && !p->old_symbol->common_block))
     {
-      /* Symbol was new.  */
+      /* Symbol was new. Or it is old, and was just put in a common
+             block  */
       if (p->attr.in_common && p->common_block && p->common_block->head)
         {
           /* If the symbol was added to any common block, it
@@ -3092,7 +3093,9 @@
         }

           if (p->common_block->head == p)
+              {
             p->common_block->head = p->common_next;
+              }
           else
         {
           gfc_symbol *cparent, *csym;
@@ -3107,25 +3110,29 @@
             }

           gcc_assert(cparent->common_next == p);
-
           cparent->common_next = csym->common_next;
         }
         }
+        }
+        if (p->gfc_new)
+          {

-      /* The derived type is saved in the symtree with the first
-         letter capitalized; the all lower-case version to the
-         derived type contains its associated generic function.  */
-      if (p->attr.flavor == FL_DERIVED)
-        gfc_delete_symtree (&p->ns->sym_root, gfc_get_string ("%c%s",
-                        (char) TOUPPER ((unsigned char) p->name[0]),
-                        &p->name[1]));
-      else
-        gfc_delete_symtree (&p->ns->sym_root, p->name);
+        /* The derived type is saved in the symtree with the first
+           letter capitalized; the all lower-case version to the
+           derived type contains its associated generic function.  */
+        if (p->attr.flavor == FL_DERIVED)
+          gfc_delete_symtree (&p->ns->sym_root, gfc_get_string ("%c%s",
+                                  (char) TOUPPER ((unsigned char) p->name[0]),
+                                  &p->name[1]));
+        else
+          gfc_delete_symtree (&p->ns->sym_root, p->name);

-      gfc_release_symbol (p);
-    }
-      else
-    restore_old_symbol (p);
+        gfc_release_symbol (p);
+      }
+        else
+          {
+            restore_old_symbol (p);
+          }
     }

   latest_undo_chgset->syms.truncate (0);

Reply via email to