Commit 2b77e908 by Francois-Xavier Coudert Committed by François-Xavier Coudert

re PR fortran/25252 (ICE on invalid code)

	PR fortran/25252

	* interface.c (gfc_current_interface_head,
	gfc_set_current_interface_head): New functions.
	* decl.c (gfc_match_modproc): Move check for syntax error earlier.
	On syntax error, restore previous state of the interface.
	* gfortran.h (gfc_current_interface_head,
	gfc_set_current_interface_head): New prototypes.

	* gfortran.dg/interface_22.f90: New test.

From-SVN: r130259
parent a0857153
2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> 2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/25252
* interface.c (gfc_current_interface_head,
gfc_set_current_interface_head): New functions.
* decl.c (gfc_match_modproc): Move check for syntax error earlier.
On syntax error, restore previous state of the interface.
* gfortran.h (gfc_current_interface_head,
gfc_set_current_interface_head): New prototypes.
2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/30285 PR fortran/30285
* module.c (struct written_common, written_commons): New structure. * module.c (struct written_common, written_commons): New structure.
(compare_written_commons, free_written_common, write_common_0): (compare_written_commons, free_written_common, write_common_0):
......
...@@ -5837,6 +5837,7 @@ gfc_match_modproc (void) ...@@ -5837,6 +5837,7 @@ gfc_match_modproc (void)
gfc_symbol *sym; gfc_symbol *sym;
match m; match m;
gfc_namespace *module_ns; gfc_namespace *module_ns;
gfc_interface *old_interface_head, *interface;
if (gfc_state_stack->state != COMP_INTERFACE if (gfc_state_stack->state != COMP_INTERFACE
|| gfc_state_stack->previous == NULL || gfc_state_stack->previous == NULL
...@@ -5856,14 +5857,29 @@ gfc_match_modproc (void) ...@@ -5856,14 +5857,29 @@ gfc_match_modproc (void)
if (module_ns == NULL) if (module_ns == NULL)
return MATCH_ERROR; 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 (;;) for (;;)
{ {
bool last = false;
m = gfc_match_name (name); m = gfc_match_name (name);
if (m == MATCH_NO) if (m == MATCH_NO)
goto syntax; goto syntax;
if (m != MATCH_YES) if (m != MATCH_YES)
return MATCH_ERROR; 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)) if (gfc_get_symbol (name, module_ns, &sym))
return MATCH_ERROR; return MATCH_ERROR;
...@@ -5877,15 +5893,26 @@ gfc_match_modproc (void) ...@@ -5877,15 +5893,26 @@ gfc_match_modproc (void)
sym->attr.mod_proc = 1; sym->attr.mod_proc = 1;
if (gfc_match_eos () == MATCH_YES) if (last)
break; break;
if (gfc_match_char (',') != MATCH_YES)
goto syntax;
} }
return MATCH_YES; return MATCH_YES;
syntax: 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); gfc_syntax_error (ST_MODULE_PROC);
return MATCH_ERROR; return MATCH_ERROR;
} }
......
...@@ -2308,6 +2308,8 @@ try gfc_extend_expr (gfc_expr *); ...@@ -2308,6 +2308,8 @@ try gfc_extend_expr (gfc_expr *);
void gfc_free_formal_arglist (gfc_formal_arglist *); void gfc_free_formal_arglist (gfc_formal_arglist *);
try gfc_extend_assign (gfc_code *, gfc_namespace *); try gfc_extend_assign (gfc_code *, gfc_namespace *);
try gfc_add_interface (gfc_symbol *); try gfc_add_interface (gfc_symbol *);
gfc_interface *gfc_current_interface_head (void);
void gfc_set_current_interface_head (gfc_interface *);
/* io.c */ /* io.c */
extern gfc_st_label format_asterisk; extern gfc_st_label format_asterisk;
......
...@@ -2707,6 +2707,52 @@ gfc_add_interface (gfc_symbol *new) ...@@ -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. /* Gets rid of a formal argument list. We do not free symbols.
Symbols are freed when a namespace is freed. */ Symbols are freed when a namespace is freed. */
......
2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/25252
* interface.c (gfc_current_interface_head,
gfc_set_current_interface_head): New functions.
* decl.c (gfc_match_modproc): Move check for syntax error earlier.
On syntax error, restore previous state of the interface.
* gfortran.h (gfc_current_interface_head,
gfc_set_current_interface_head): New prototypes.
2007-11-17 Richard Guenther <rguenther@suse.de> 2007-11-17 Richard Guenther <rguenther@suse.de>
PR middle-end/34130 PR middle-end/34130
! { 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment