diff options
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r-- | gcc/fortran/decl.c | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index be197bc..325d012 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -5837,6 +5837,7 @@ gfc_match_modproc (void) gfc_symbol *sym; match m; gfc_namespace *module_ns; + gfc_interface *old_interface_head, *interface; if (gfc_state_stack->state != COMP_INTERFACE || gfc_state_stack->previous == NULL @@ -5856,14 +5857,29 @@ gfc_match_modproc (void) if (module_ns == NULL) return MATCH_ERROR; + /* Store the current state of the interface. We will need it if we + end up with a syntax error and need to recover. */ + old_interface_head = gfc_current_interface_head (); + for (;;) { + bool last = false; + m = gfc_match_name (name); if (m == MATCH_NO) goto syntax; if (m != MATCH_YES) return MATCH_ERROR; + /* Check for syntax error before starting to add symbols to the + current namespace. */ + if (gfc_match_eos () == MATCH_YES) + last = true; + if (!last && gfc_match_char (',') != MATCH_YES) + goto syntax; + + /* Now we're sure the syntax is valid, we process this item + further. */ if (gfc_get_symbol (name, module_ns, &sym)) return MATCH_ERROR; @@ -5877,15 +5893,26 @@ gfc_match_modproc (void) sym->attr.mod_proc = 1; - if (gfc_match_eos () == MATCH_YES) + if (last) break; - if (gfc_match_char (',') != MATCH_YES) - goto syntax; } return MATCH_YES; syntax: + /* Restore the previous state of the interface. */ + interface = gfc_current_interface_head (); + gfc_set_current_interface_head (old_interface_head); + + /* Free the new interfaces. */ + while (interface != old_interface_head) + { + gfc_interface *i = interface->next; + gfc_free (interface); + interface = i; + } + + /* And issue a syntax error. */ gfc_syntax_error (ST_MODULE_PROC); return MATCH_ERROR; } |