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. Bootstrapped&tested 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 +