re PR middle-end/40043 (ICE with nested try/catch)

* g++.dg/eh/nested-try.C: New test.

	PR middle-end/40043
	* except.c (copy_eh_region): Always set prev_try.
	(redirect_eh_edge_to_label): Find outer try.
	(foreach_reachable_handler): When looking for prev try
	handle case where previous try is not going to be taken.

From-SVN: r147317
This commit is contained in:
Jan Hubicka 2009-05-09 12:52:24 +02:00 committed by Jan Hubicka
parent 7925c06c0b
commit 0afd721984
4 changed files with 56 additions and 5 deletions

View File

@ -1,3 +1,11 @@
2009-05-09 Jan Hubicka <jh@suse.cz>
PR middle-end/40043
* except.c (copy_eh_region): Always set prev_try.
(redirect_eh_edge_to_label): Find outer try.
(foreach_reachable_handler): When looking for prev try
handle case where previous try is not going to be taken.
2009-05-07 Michael Meissner <meissner@linux.vnet.ibm.com>
PR tree-optimization/40049

View File

@ -1410,9 +1410,9 @@ copy_eh_region (struct eh_region *old, struct eh_region *new_outer,
{
gcc_assert (old->type != ERT_TRY);
r = copy_eh_region_1 (old, new_outer);
if (r->type == ERT_CLEANUP && prev_try_map)
if (r->type == ERT_CLEANUP)
{
gcc_assert (r->u.cleanup.prev_try);
gcc_assert (r->u.cleanup.prev_try || !prev_try_map);
r->u.cleanup.prev_try = prev_try_map;
}
return r;
@ -1477,7 +1477,7 @@ struct eh_region *
redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
bool inlinable_call, int region_number)
{
struct eh_region *outer, *prev_try_map = NULL;
struct eh_region *outer, *prev_try_map;
struct eh_region *region;
VEC (eh_region, heap) * trace = NULL;
int i;
@ -1539,6 +1539,7 @@ redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
}
outer = VEC_index (eh_region, trace, start_here)->outer;
gcc_assert (start_here >= 0);
prev_try_map = find_prev_try (outer);
/* And now do the dirty job! */
for (i = start_here; i >= 0; i--)
@ -3120,8 +3121,20 @@ foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call,
to the next outer cleanup region, so the flow graph will be
accurate. */
if (region->type == ERT_CLEANUP)
region = region->u.cleanup.prev_try;
else
{
enum reachable_code code = RNL_NOT_CAUGHT;
region = region->u.cleanup.prev_try;
/* Continue looking for outer TRY region until we find one
that might cath something. */
while (region
&& (code = reachable_next_level (region, type_thrown, &info,
inlinable_call || is_resx))
== RNL_NOT_CAUGHT)
region = find_prev_try (region->outer);
if (code >= RNL_CAUGHT)
break;
}
if (region)
region = region->outer;
}
}

View File

@ -1,3 +1,8 @@
2009-05-09 Jan Hubicka <jh@suse.cz>
PR middle-end/40043
* g++.dg/eh/nested-try.C: New test.
2009-05-08 Michael Meissner <meissner@linux.vnet.ibm.com>
PR tree-optimization/40049

View File

@ -0,0 +1,25 @@
// { dg-do compile }
// Nested try statements shadowing each other was crashing in EH edge redirection.
// PR middle-end/40043
struct A
{
~A();
void foo();
};
void bar()
{
A a;
try
{
A b;
try
{
b.foo();
}
catch (int) {}
}
catch (int) {}
}