aboutsummaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-03-17 06:09:30 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-03-17 06:09:30 +0000
commitbafb714bac23b833d326cfdeb6ef3d58965640a5 (patch)
treee517b3e747497dcfd5c40ea4efb3157765c7da39 /gcc/except.c
parent30492adf69319654cb870eb4634dc53164d3cbc0 (diff)
downloadgcc-bafb714bac23b833d326cfdeb6ef3d58965640a5.zip
gcc-bafb714bac23b833d326cfdeb6ef3d58965640a5.tar.gz
gcc-bafb714bac23b833d326cfdeb6ef3d58965640a5.tar.bz2
re PR c++/8805 (compile time regression with many member variables)
PR c++/8805 * except.c (eh_region_u_cleanup): Add prev_try. (expand_eh_region_end_cleanup): Set it. (reachable_handlers): Use it to skip over cleanup blocks. PR c++/8805 * g++.dg/eh/cleanup1.C: New test. From-SVN: r64465
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/gcc/except.c b/gcc/except.c
index 16613c4..3c80f60 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -186,6 +186,7 @@ struct eh_region GTY(())
we can match up fixup regions. */
struct eh_region_u_cleanup {
tree exp;
+ struct eh_region *prev_try;
} GTY ((tag ("ERT_CLEANUP"))) cleanup;
/* The real region (by expression and by pointer) that fixup code
@@ -553,6 +554,7 @@ expand_eh_region_end_cleanup (handler)
region->type = ERT_CLEANUP;
region->label = gen_label_rtx ();
region->u.cleanup.exp = handler;
+ region->u.cleanup.prev_try = cfun->eh->try_region;
around_label = gen_label_rtx ();
emit_jump (around_label);
@@ -2762,10 +2764,20 @@ reachable_handlers (insn)
region = region->outer;
}
- for (; region; region = region->outer)
- if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
- break;
-
+ while (region)
+ {
+ if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
+ break;
+ /* If we have processed one cleanup, there is no point in
+ processing any more of them. Each cleanup will have an edge
+ 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
+ region = region->outer;
+ }
+
return info.handlers;
}