Re: [patch] PR fortran/61669
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
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
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