backport: 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>

	Backport from trunk
	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>

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

From-SVN: r195687
This commit is contained in:
Thomas Koenig 2013-02-02 22:38:14 +00:00
parent 40c41aee50
commit 3e946527c4
6 changed files with 66 additions and 1 deletions

View File

@ -1,3 +1,13 @@
2013-02-02 Thomas Koenig <tkoenig@gcc.gnu.org>
Backport from trunk
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-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline

View File

@ -5896,6 +5896,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)
@ -6121,6 +6123,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

@ -4283,6 +4283,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))
@ -4296,6 +4297,7 @@ parse_module (void)
st = parse_spec (ST_NONE);
error = false;
loop:
switch (st)
{
@ -4314,12 +4316,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,11 @@
2013-02-02 Thomas Koenig <tkoenig@gcc.gnu.org>
Backport from trunk
PR fortran/50627
PR fortran/56054
* gfortran.dg/block_12.f90: New test.
* gfortran.dg/module_error_1.f90: New test.
2013-02-01 Jakub Jelinek <jakub@redhat.com>
Backported from mainline

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