Index: interface.c
===================================================================
--- interface.c	(revision 130234)
+++ interface.c	(working copy)
@@ -2707,6 +2707,52 @@ gfc_add_interface (gfc_symbol *new)
 }
 
 
+gfc_interface *
+gfc_current_interface_head (void)
+{
+  switch (current_interface.type)
+    {
+      case INTERFACE_INTRINSIC_OP:
+	return current_interface.ns->operator[current_interface.op];
+	break;
+
+      case INTERFACE_GENERIC:
+	return current_interface.sym->generic;
+	break;
+
+      case INTERFACE_USER_OP:
+	return current_interface.uop->operator;
+	break;
+
+      default:
+	gcc_unreachable ();
+    }
+}
+
+
+void
+gfc_set_current_interface_head (gfc_interface *i)
+{
+  switch (current_interface.type)
+    {
+      case INTERFACE_INTRINSIC_OP:
+	current_interface.ns->operator[current_interface.op] = i;
+	break;
+
+      case INTERFACE_GENERIC:
+	current_interface.sym->generic = i;
+	break;
+
+      case INTERFACE_USER_OP:
+	current_interface.uop->operator = i;
+	break;
+
+      default:
+	gcc_unreachable ();
+    }
+}
+
+
 /* Gets rid of a formal argument list.  We do not free symbols.
    Symbols are freed when a namespace is freed.  */
 
Index: decl.c
===================================================================
--- decl.c	(revision 130234)
+++ decl.c	(working copy)
@@ -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;
 }
Index: gfortran.h
===================================================================
--- gfortran.h	(revision 130234)
+++ gfortran.h	(working copy)
@@ -2308,6 +2308,8 @@ try gfc_extend_expr (gfc_expr *);
 void gfc_free_formal_arglist (gfc_formal_arglist *);
 try gfc_extend_assign (gfc_code *, gfc_namespace *);
 try gfc_add_interface (gfc_symbol *);
+gfc_interface *gfc_current_interface_head (void);
+void gfc_set_current_interface_head (gfc_interface *);
 
 /* io.c */
 extern gfc_st_label format_asterisk;
Index: gfortran.dg/interface_22.f90
===================================================================
--- gfortran.dg/interface_22.f90	(revision 0)
+++ gfortran.dg/interface_22.f90	(revision 0)
@@ -0,0 +1,25 @@
+! { dg-do compile }
+!
+! This is a check for error recovery: we used to ICE in various places, or
+! emit bogus error messages (PR 25252)
+!
+module foo
+  interface bar
+    module procedure X, Y, ! { dg-error "Syntax error in MODULE PROCEDURE statement" }
+  end interface bar
+end module
+
+module g
+  interface i
+    module procedure sint => sreal ! { dg-error "Syntax error in MODULE PROCEDURE statement" }
+  end interface i
+end module g
+
+module gswap
+  type points
+    real :: x, y
+  end type points
+  interface swap
+    module procedure sreal, schar, sint => sreal ! { dg-error "Syntax error in MODULE PROCEDURE statement" }
+  end interface swap
+end module gswap
