re PR fortran/50627 (Error recovery: ICE in gfc_free_namespace after diagnosing missing end of construct)

2013-02-02  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/50627
	PR fortran/56054
	* decl.c (gfc_match_end):  Remove half-ready namespace
	from parent if the end of a block is missing.
	* parse.c (parse_module):  Do not put namespace into
	gsymbol on error.

2013-02-02  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/50627
	PR fortran/56054
	* gfortran.dg/block_12.f90:  New test.
	* gfortran.dg/module_error_1.f90:  New test.

From-SVN: r195684
This commit is contained in:
Thomas Koenig 2013-02-02 09:50:58 +00:00
parent 18d2405e9d
commit 0cab6b73df
6 changed files with 64 additions and 1 deletions

View File

@ -1,3 +1,12 @@
2013-02-02 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/50627
PR fortran/56054
* decl.c (gfc_match_end): Remove half-ready namespace
from parent if the end of a block is missing.
* parse.c (parse_module): Do not put namespace into
gsymbol on error.
2012-01-30 Tobias Burnus <burnus@net-b.de>
PR fortran/56138

View File

@ -5955,6 +5955,8 @@ gfc_match_end (gfc_statement *st)
const char *target;
int eos_ok;
match m;
gfc_namespace *parent_ns, *ns, *prev_ns;
gfc_namespace **nsp;
old_loc = gfc_current_locus;
if (gfc_match ("end") != MATCH_YES)
@ -6180,6 +6182,35 @@ syntax:
cleanup:
gfc_current_locus = old_loc;
/* If we are missing an END BLOCK, we created a half-ready namespace.
Remove it from the parent namespace's sibling list. */
if (state == COMP_BLOCK)
{
parent_ns = gfc_current_ns->parent;
nsp = &(gfc_state_stack->previous->tail->ext.block.ns);
prev_ns = NULL;
ns = *nsp;
while (ns)
{
if (ns == gfc_current_ns)
{
if (prev_ns == NULL)
*nsp = NULL;
else
prev_ns->sibling = ns->sibling;
}
prev_ns = ns;
ns = ns->sibling;
}
gfc_free_namespace (gfc_current_ns);
gfc_current_ns = parent_ns;
}
return MATCH_ERROR;
}

View File

@ -4291,6 +4291,7 @@ parse_module (void)
{
gfc_statement st;
gfc_gsymbol *s;
bool error;
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined || (s->type != GSYM_UNKNOWN && s->type != GSYM_MODULE))
@ -4304,6 +4305,7 @@ parse_module (void)
st = parse_spec (ST_NONE);
error = false;
loop:
switch (st)
{
@ -4322,12 +4324,15 @@ loop:
gfc_error ("Unexpected %s statement in MODULE at %C",
gfc_ascii_statement (st));
error = true;
reject_statement ();
st = next_statement ();
goto loop;
}
s->ns = gfc_current_ns;
/* Make sure not to free the namespace twice on error. */
if (!error)
s->ns = gfc_current_ns;
}

View File

@ -1,3 +1,10 @@
2013-02-02 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/50627
PR fortran/56054
* gfortran.dg/block_12.f90: New test.
* gfortran.dg/module_error_1.f90: New test.
2013-02-02 Richard Sandiford <rdsandiford@googlemail.com>
* lib/target-supports.exp (check_effective_target_vect_float)

View File

@ -0,0 +1,6 @@
! { dg-do compile }
! PR 50627 - this used to free a namespace twice.
program main
block
end program main ! { dg-error "END BLOCK" }
! { dg-prune-output "Unexpected end of file" }

View File

@ -0,0 +1,5 @@
! { dg-do compile }
! PR fortran/50627
module kernels
select type (args) ! { dg-error "Unexpected SELECT TYPE" }
end module kernels