Re: [patch] PR fortran/61669

2014-12-15 Thread Jakub Jelinek
On Sat, Aug 23, 2014 at 06:59:14PM +0200, Paul Richard Thomas wrote:
 Dear Steven,
 
 I am constantly amazed that data statement bugs keep turning up:-)
 Anyway, your fix is fine for trunk and, if you feel so inclined, 4.8
 and 4.9.

Steven didn't respond to my ping about this PR, so I've updated the
testcase, bootstrapped/regtested it on x86_64-linux and i686-linux
and committed to trunk.

I'll put it into 4.9/4.8 later on.

2014-12-15  Steven Bosscher  ste...@gcc.gnu.org
Jakub Jelinek  ja...@redhat.com

PR fortran/61669
* gfortran.h (struct gfc_namespace): Add OLD_DATA field.
* decl.c (gfc_reject_data): New function.
* parse.c *use_modules): Record roll-back point.
(next_statement): Likewise.
(reject_statement): Roll back to last accepted DATA.

* gfortran.dg/pr61669.f90: New test.

--- gcc/fortran/gfortran.h  (revision 214350)
+++ gcc/fortran/gfortran.h  (working copy)
@@ -1625,7 +1625,7 @@ typedef struct gfc_namespace
   gfc_st_label *st_labels;
   /* This list holds information about all the data initializers in
  this namespace.  */
-  struct gfc_data *data;
+  struct gfc_data *data, *old_data;
 
   gfc_charlen *cl_list, *old_cl_list;
 
@@ -2941,6 +2941,7 @@ void gfc_free_omp_namelist (gfc_omp_namelist *);
 void gfc_free_equiv (gfc_equiv *);
 void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
 void gfc_free_data (gfc_data *);
+void gfc_reject_data (gfc_namespace *);
 void gfc_free_case_list (gfc_case *);
 
 /* matchexp.c -- FIXME too?  */
--- gcc/fortran/decl.c  (revision 214350)
+++ gcc/fortran/decl.c  (working copy)
@@ -178,7 +178,21 @@ gfc_free_data_all (gfc_namespace *ns)
 }
 }
 
+/* Reject data parsed since the last restore point was marked.  */
 
+void
+gfc_reject_data (gfc_namespace *ns)
+{
+  gfc_data *d;
+
+  while (ns-data  ns-data != ns-old_data)
+{
+  d = ns-data-next;
+  free (ns-data);
+  ns-data = d;
+}
+}
+
 static match var_element (gfc_data_variable *);
 
 /* Match a list of variables terminated by an iterator and a right
--- gcc/fortran/parse.c (revision 214350)
+++ gcc/fortran/parse.c (working copy)
@@ -118,6 +118,7 @@ use_modules (void)
   gfc_warning_check ();
   gfc_current_ns-old_cl_list = gfc_current_ns-cl_list;
   gfc_current_ns-old_equiv = gfc_current_ns-equiv;
+  gfc_current_ns-old_data = gfc_current_ns-data;
   last_was_use_stmt = false;
 }
 
@@ -1097,6 +1098,7 @@ next_statement (void)
 
   gfc_current_ns-old_cl_list = gfc_current_ns-cl_list;
   gfc_current_ns-old_equiv = gfc_current_ns-equiv;
+  gfc_current_ns-old_data = gfc_current_ns-data;
   for (;;)
 {
   gfc_statement_label = NULL;
@@ -2045,6 +2047,8 @@ reject_statement (void)
   gfc_free_equiv_until (gfc_current_ns-equiv, gfc_current_ns-old_equiv);
   gfc_current_ns-equiv = gfc_current_ns-old_equiv;
 
+  gfc_reject_data (gfc_current_ns);
+
   gfc_new_block = NULL;
   gfc_undo_symbols ();
   gfc_clear_warning ();
--- gcc/testsuite/gfortran.dg/pr61669.f90   (revision 0)
+++ gcc/testsuite/gfortran.dg/pr61669.f90   (working copy)
@@ -0,0 +1,7 @@
+! { dg-do compile }
+  write (*,(a)) char(12)
+  CHARACTER*80 A /A/  ! { dg-error Unexpected data declaration 
statement }
+  REAL*4 B  ! { dg-error Unexpected data declaration 
statement }
+  write (*,(a)) char(12)
+  DATA B / 0.02 /   ! { dg-warning Obsolescent feature: DATA 
statement }
+  END


Jakub


[patch] PR fortran/61669

2014-08-23 Thread Steven Bosscher
Hello,

This bug is an error recovery issue. A data declaration is parsed and
accepted, and added to gfc_current_ns-data, but the statement is
rejected. The rejected data decl is not rolled back, causing memory
corruption later on.

Proposed fix is to roll back DATA for rejected statements.

Bootstrappedtested on powerpc64-unknown-linux-gnu. OK for trunk?

Ciao!
Steven
fortran/
PR fortran/61669
* gfortran.h (struct gfc_namespace): Add OLD_DATA field.
* decl.c (gfc_reject_data): New function.
* parse.c *use_modules): Record roll-back point.
(next_statement): Likewise.
(reject_statement): Roll back to last accepted DATA.

testsuite/
PR fortran/61669
* gfortran.dg/pr61669.f90: New test.

Index: fortran/gfortran.h
===
--- fortran/gfortran.h  (revision 214350)
+++ fortran/gfortran.h  (working copy)
@@ -1625,7 +1625,7 @@ typedef struct gfc_namespace
   gfc_st_label *st_labels;
   /* This list holds information about all the data initializers in
  this namespace.  */
-  struct gfc_data *data;
+  struct gfc_data *data, *old_data;
 
   gfc_charlen *cl_list, *old_cl_list;
 
@@ -2941,6 +2941,7 @@ void gfc_free_omp_namelist (gfc_omp_namelist *);
 void gfc_free_equiv (gfc_equiv *);
 void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
 void gfc_free_data (gfc_data *);
+void gfc_reject_data (gfc_namespace *);
 void gfc_free_case_list (gfc_case *);
 
 /* matchexp.c -- FIXME too?  */
Index: fortran/decl.c
===
--- fortran/decl.c  (revision 214350)
+++ fortran/decl.c  (working copy)
@@ -178,7 +178,21 @@ gfc_free_data_all (gfc_namespace *ns)
 }
 }
 
+/* Reject data parsed since the last restore point was marked.  */
 
+void
+gfc_reject_data (gfc_namespace *ns)
+{
+  gfc_data *d;
+
+  while (ns-data  ns-data != ns-old_data)
+{
+  d = ns-data-next;
+  free (ns-data);
+  ns-data = d;
+}
+}
+
 static match var_element (gfc_data_variable *);
 
 /* Match a list of variables terminated by an iterator and a right
Index: fortran/parse.c
===
--- fortran/parse.c (revision 214350)
+++ fortran/parse.c (working copy)
@@ -118,6 +118,7 @@ use_modules (void)
   gfc_warning_check ();
   gfc_current_ns-old_cl_list = gfc_current_ns-cl_list;
   gfc_current_ns-old_equiv = gfc_current_ns-equiv;
+  gfc_current_ns-old_data = gfc_current_ns-data;
   last_was_use_stmt = false;
 }
 
@@ -1097,6 +1098,7 @@ next_statement (void)
 
   gfc_current_ns-old_cl_list = gfc_current_ns-cl_list;
   gfc_current_ns-old_equiv = gfc_current_ns-equiv;
+  gfc_current_ns-old_data = gfc_current_ns-data;
   for (;;)
 {
   gfc_statement_label = NULL;
@@ -2045,6 +2047,8 @@ reject_statement (void)
   gfc_free_equiv_until (gfc_current_ns-equiv, gfc_current_ns-old_equiv);
   gfc_current_ns-equiv = gfc_current_ns-old_equiv;
 
+  gfc_reject_data (gfc_current_ns);
+
   gfc_new_block = NULL;
   gfc_undo_symbols ();
   gfc_clear_warning ();
Index: testsuite/gfortran.dg/pr61669.f90
===
--- testsuite/gfortran.dg/pr61669.f90   (revision 0)
+++ testsuite/gfortran.dg/pr61669.f90   (working copy)
@@ -0,0 +1,8 @@
+! { dg-do compile }
+  write (*,(a)) char(12)
+  CHARACTER*80 A /A/  ! { dg-error Unexpected data declaration 
statement }
+  REAL*4 B  ! { dg-error Unexpected data declaration 
statement }
+  write (*,(a)) char(12)
+  DATA B / 0.02 /
+  END
+


Re: [patch] PR fortran/61669

2014-08-23 Thread Paul Richard Thomas
Dear Steven,

I am constantly amazed that data statement bugs keep turning up:-)
Anyway, your fix is fine for trunk and, if you feel so inclined, 4.8
and 4.9.

Thanks

Paul

On 23 August 2014 16:52, Steven Bosscher stevenb@gmail.com wrote:
 Hello,

 This bug is an error recovery issue. A data declaration is parsed and
 accepted, and added to gfc_current_ns-data, but the statement is
 rejected. The rejected data decl is not rolled back, causing memory
 corruption later on.

 Proposed fix is to roll back DATA for rejected statements.

 Bootstrappedtested on powerpc64-unknown-linux-gnu. OK for trunk?

 Ciao!
 Steven



-- 
The knack of flying is learning how to throw yourself at the ground and miss.
   --Hitchhikers Guide to the Galaxy