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:
parent
7925c06c0b
commit
0afd721984
@ -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
|
||||
|
23
gcc/except.c
23
gcc/except.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
25
gcc/testsuite/g++.dg/eh/nested-try.C
Normal file
25
gcc/testsuite/g++.dg/eh/nested-try.C
Normal 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) {}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user