From 31fee91edf762ff41ab637698c855cb201e4e6cb Mon Sep 17 00:00:00 2001
From: Mikael Morin <mikael@gcc.gnu.org>
Date: Sun, 25 Jul 2010 17:01:15 +0000
Subject: [PATCH] re PR fortran/44660 (ICE in resolve_equivalence())

2010-07-25  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/44660
	* gfortran.h (gfc_namespace): New field old_equiv.
	(gfc_free_equiv_until): New prototype.
	* match.c (gfc_free_equiv_until): New, renamed from gfc_free_equiv with
	a parameterized stop condition.
	(gfc_free_equiv): Use gfc_free_equiv_until.
	* parse.c (next_statement): Save equivalence list.
	(reject_statement): Restore equivalence list.

From-SVN: r162516
---
 gcc/fortran/ChangeLog  | 11 +++++++++++
 gcc/fortran/gfortran.h |  3 ++-
 gcc/fortran/match.c    | 13 ++++++++++---
 gcc/fortran/parse.c    |  4 ++++
 4 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 3627b9e1b4a9..c6d786e3decb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -78,6 +78,17 @@
 	* dependency.c (gfc_check_dependency): Add argument alising check.
 	* symbol.c (gfc_symbols_could_alias): Add argument alising check.
 
+2010-07-25  Mikael Morin  <mikael@gcc.gnu.org>
+
+	PR fortran/44660
+	* gfortran.h (gfc_namespace): New field old_equiv.
+	(gfc_free_equiv_until): New prototype.
+	* match.c (gfc_free_equiv_until): New, renamed from gfc_free_equiv with
+	a parameterized stop condition.
+	(gfc_free_equiv): Use gfc_free_equiv_until.
+	* parse.c (next_statement): Save equivalence list.
+	(reject_statement): Restore equivalence list. 
+
 2010-07-22  Daniel Kraft  <d@domob.eu>
 
 	* trans-stmt.c (gfc_trans_return): Put back in the handling of se.post,
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a493866ab369..70cc4fdccbe5 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1355,7 +1355,7 @@ typedef struct gfc_namespace
   struct gfc_code *code;
 
   /* Points to the equivalences set up in this namespace.  */
-  struct gfc_equiv *equiv;
+  struct gfc_equiv *equiv, *old_equiv;
 
   /* Points to the equivalence groups produced by trans_common.  */
   struct gfc_equiv_list *equiv_lists;
@@ -2611,6 +2611,7 @@ void gfc_free_forall_iterator (gfc_forall_iterator *);
 void gfc_free_alloc_list (gfc_alloc *);
 void gfc_free_namelist (gfc_namelist *);
 void gfc_free_equiv (gfc_equiv *);
+void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
 void gfc_free_data (gfc_data *);
 void gfc_free_case_list (gfc_case *);
 
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 92580e359dbd..bd73929b8659 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -4035,18 +4035,25 @@ gfc_match_module (void)
    do this.  */
 
 void
-gfc_free_equiv (gfc_equiv *eq)
+gfc_free_equiv_until (gfc_equiv *eq, gfc_equiv *stop)
 {
-  if (eq == NULL)
+  if (eq == stop)
     return;
 
   gfc_free_equiv (eq->eq);
-  gfc_free_equiv (eq->next);
+  gfc_free_equiv_until (eq->next, stop);
   gfc_free_expr (eq->expr);
   gfc_free (eq);
 }
 
 
+void
+gfc_free_equiv (gfc_equiv *eq)
+{
+  gfc_free_equiv_until (eq, NULL);
+}
+
+
 /* Match an EQUIVALENCE statement.  */
 
 match
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 616fb50ec673..1575b2b37efe 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -892,6 +892,7 @@ next_statement (void)
   gfc_new_block = NULL;
 
   gfc_current_ns->old_cl_list = gfc_current_ns->cl_list;
+  gfc_current_ns->old_equiv = gfc_current_ns->equiv;
   for (;;)
     {
       gfc_statement_label = NULL;
@@ -1651,6 +1652,9 @@ reject_statement (void)
   gfc_free_charlen (gfc_current_ns->cl_list, gfc_current_ns->old_cl_list);
   gfc_current_ns->cl_list = gfc_current_ns->old_cl_list;
 
+  gfc_free_equiv_until (gfc_current_ns->equiv, gfc_current_ns->old_equiv);
+  gfc_current_ns->equiv = gfc_current_ns->old_equiv;
+
   gfc_new_block = NULL;
   gfc_undo_symbols ();
   gfc_clear_warning ();
-- 
GitLab