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
This commit is contained in:
Francois-Xavier Coudert 2007-11-17 17:49:45 +00:00 committed by François-Xavier Coudert
parent a0857153dd
commit 2b77e90812
6 changed files with 123 additions and 3 deletions

View File

@ -1,3 +1,13 @@
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

View File

@ -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;
}

View File

@ -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;

View File

@ -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. */

View File

@ -1,3 +1,13 @@
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>
PR middle-end/34130

View File

@ -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