aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-05-09 12:52:24 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2009-05-09 10:52:24 +0000
commit0afd721984444224c371c811504d7db8eccf9fce (patch)
treea32d4999485d8f15ac31567a5b4910e7ca7f29f7 /gcc
parent7925c06c0b5cfd69e7b07581468006b1b3aa50a1 (diff)
downloadgcc-0afd721984444224c371c811504d7db8eccf9fce.zip
gcc-0afd721984444224c371c811504d7db8eccf9fce.tar.gz
gcc-0afd721984444224c371c811504d7db8eccf9fce.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/except.c23
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/eh/nested-try.C25
4 files changed, 56 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dccd02f..2c5b52e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/except.c b/gcc/except.c
index 3ba3b67..df28a98 100644
--- a/gcc/except.c
+++ b/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;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3099e1b..c2fb1d3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/eh/nested-try.C b/gcc/testsuite/g++.dg/eh/nested-try.C
new file mode 100644
index 0000000..5796f9a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/nested-try.C
@@ -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) {}
+}