aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r--gcc/fortran/decl.c33
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;
}