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