mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 06:50:27 +08:00
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:
parent
a0857153dd
commit
2b77e90812
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
25
gcc/testsuite/gfortran.dg/interface_22.f90
Normal file
25
gcc/testsuite/gfortran.dg/interface_22.f90
Normal 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
|
Loading…
x
Reference in New Issue
Block a user